[英]Using a generic with an unspecified type parameter as a value in a Dictionary
我正在寫一個方法,該方法根據傳入的類型為加載過程返回類的不同實例。
我嘗試編寫的方法將像這樣使用:
Loader<MyType> loader = context.GetLoader<MyType>();
loader.Load(myTypeArray);
在內部,我計划使用加載程序作為值保留Dictionary<Type, T>
。 但是,我不確定T
應該是哪種類型。
我可以創建T
object
,但我更喜歡將其保留為某種Loader<>
。 我知道我需要以任何一種方式進行轉換,但是使用Loader<>
會帶來更多類型安全性。
有什么好的方法可以實現嗎?
您有兩種選擇。 兩者都需要您添加接口。
添加一個普通的ILoader
(沒有類型參數)接口,並在您的加載器中將其實現為class Loader<T> : ILoader
。 公共接口將允許您將所有加載器存儲在List<ILoader>
。
interface ILoader {} class Loader<T> : ILoader {} void Example() { var loaders = new List<ILoader>(); loaders.Add( new Loader<Foo>() ); loaders.Add( new Loader<Bar>() ); }
定義一個新的協變接口ILoader<out T>
並將其在Loader中實現為class Loader<T> : ILoader<T>
。 協方差將允許您將所有加載器存儲在List<ILoader<object>>
。 僅當T
是引用類型時,此選項才有效;並且僅當您的接口方法都不接受T
作為參數時,此選項才可行。
interface ILoader<out T> { //void SetLoader(T input); //Does not compile due to covariance T GetLoader(); //Read is allowed } class Loader<T> : ILoader<T> { public void SetLoader(T input) {} //Works when not in interface public T GetLoader() { return default(T); } } void Example() { var loaders = new List<ILoader<object>>(); loaders.Add( new Loader<Foo>() ); loaders.Add( new Loader<Bar>() ); }
我可以創建
T
object
,但我更喜歡將其保留為某種Loader<>
。 我知道我需要以任何一種方式進行轉換,但是使用Loader<>
會帶來更多類型安全性。
不,它不會; 這句話自相矛盾! 您都說“我知道我需要強制轉換”,所以編譯時類型安全性已經為零 ,並且您可以獲得更多類型安全性,但是零並不等於零!
請記住,保留表示形式的強制轉換的功能恰好是“我知道編譯器在編譯時不知道的在運行時將是正確的事實”。 那是演員陣容的目的 。
在C#類型系統中沒有辦法表示“這是C<?>
類型的東西,所以不要試圖找到一個。 您已經接受了運行時類型檢查,因此繼續吧。 您的dict[typeof(T)]
會產生類型為Loader<T>
的變量; 唯一可以保持不變的人就是您 ,因此甚至不要嘗試依賴編譯器為您完成此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.