我想宣告類似的東西:
public class ImpostorClassWithAddedNotificationSupport<T> : T, ICustomTypeProvider, INotifyPropertyChanged where T : class
但我收到此錯誤:
CS0689:無法從“T”派生,因為它是型別引數
我想用我的類動態地向屬性添加新行為(覆寫基類屬性)。我類的每個屬性都會呼叫基類屬性,然后向它添加通知。我還會添加更多功能(方法)。這樣,一切都可以在設計中正常作業,但對派生類具有額外的功能。一種模仿(冒名頂替者)以添加更多功能。
有沒有辦法動態覆寫型別以添加??功能(例如通知等功能)?如果是,如何?如果不是,為什么?
我的初衷是:
我嘗試做一個模仿我想編輯的任何物件的 FakeObject。它將動態創建它模仿的任何物件的所有屬性。然后我可以編輯那個“FakeObject”,如果我想取消,我重繪 那個 fakeObject 并且我的原始物件從未被修改過(就像任何對話框上的“取消”)。在“確定”時,它將對原始物件應用更改。它已經適用于 PropertyGrid,因為 PropertyGrid 使用后面的反射來發現和讀取/寫入屬性。但我想在設計時將我的課程與 WPF 和 WinUI 一起使用。通知部分只是附帶的獎勵。否則我必須撰寫一個“復制建構式”或任何類似的復制機制,而且我必須在每個類上實作 INotifyPropertyChanged。我寧愿保持我的課程“簡單” - POCO。
問了之后才明白
實際上是不可能的。我應該向微軟索要一項新功能。
uj5u.com熱心網友回復:
不,這不能以這種方式實作,如編譯器錯誤所示。基本上,泛型允許您圍繞該泛型型別撰寫一個類,而無需對其了解太多,除了您對其施加的約束,例如 where T : class。所以它對于編譯器來說有太多的未知數。請記住,泛型類可以使用不在其程式集中的東西的泛型型別,例如 List 如何在 MS 程式集中而 Foo 在您的自定義程式集中。基類在編譯時需要在派生類的可見程式集中。
您可以在此處查看 MS 檔案或在此處查看MS 博客文章。
不過,好問題。這些型別的問題確實有助于充實對 C# 和 OO 的理解,以及它的能力和局限在哪里。
uj5u.com熱心網友回復:
這在 .Net 中根本不可能。
由于您不知道什么T是您不能覆寫任何方法,也不能在其上呼叫任何方法。如果您添加介面約束以提供這種可能性,您可以直接從該介面繼承并創建一個常規裝飾器。
所以我假設你會想要某種模板來包裝你想要裝飾的型別中的每個方法,以提供諸如日志記錄之類的東西。而且這個概念可能需要對 IL 格式和運行時進行重大更改才能支持。
一種可能的解決方法是使用反射在運行時動態地發出新型別。另一種可能是使用注釋來重寫程式集中的 IL 代碼,以向方法添加額外的功能。我相信這是PostSharp使用的方法。
uj5u.com熱心網友回復:
所以你真正想要的是這樣的:
MyClass x = new AddNotificationSupport<MyClass>();
何時AddNotificationSupport<>實作裝飾器或代理(從未了解兩者之間的區別)。我認為您最好的方法是Castle.DynamicProxy專案。這是一個很好的教程來了解它是如何作業的以及你可以用它做什么:https ://kozmic.net/dynamic-proxy-tutorial/
更新:
在您對問題進行編輯之后。您可以將某些課程ChangeTracker與原始課程混合。然后實作一個攔截器來裝飾所需的方法和屬性。該類應該“記住”代理上應用的所有更改,并提供通過呼叫擴展方法ChangeTracker來恢復它們的能力。Cancel
此代碼可以幫助您開始:
public static T AsTrackable<T>(this T target)
where T : class
{
if (target == null)
{
return null;
}
if (target is ITrackableObject)
{
return target;
}
var options = new ProxyGenerationOptions { Hook = new TrackableHook() };
options.AddMixinInstance(new TrackableObject());
var interceptor = new TrackSettersInterceptor();
var result = (T)_proxyGenerator.CreateClassProxyWithTarget(
typeof(T),
new[] { typeof(ITrackableObject) },
target,
options,
interceptor);
return result;
}
您需要實作TrackableObject,TrackableHook和TrackSettersInterceptor.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/479835.html
上一篇:Python是如何讀取代碼的?在這種情況下按什么順序
下一篇:如何鏈接父子css變換變數
