簡體   English   中英

在字典中使用帶有未指定類型參數的泛型作為值

[英]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<>會帶來更多類型安全性。

有什么好的方法可以實現嗎?

您有兩種選擇。 兩者都需要您添加接口。

  1. 添加一個普通的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>() ); } 
  2. 定義一個新的協變接口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>() ); } 

DotNetFiddle上的代碼示例

我可以創建T object ,但我更喜歡將其保留為某種Loader<> 我知道我需要以任何一種方式進行轉換,但是使用Loader<>會帶來更多類型安全性。

不,它不會; 這句話自相矛盾! 您都說“我知道我需要強制轉換”,所以編譯時類型安全性已經為零 ,並且您可以獲得更多類型安全性,但是零並不等於零!

請記住,保留表示形式的強制轉換的功能恰好是“我知道編譯器在編譯時不知道的在運行時將是正確的事實”。 那是演員陣容的目的

在C#類型系統中沒有辦法表示“這是C<?>類型的東西,所以不要試圖找到一個。 您已經接受了運行時類型檢查,因此繼續吧。 您的dict[typeof(T)]會產生類型為Loader<T>的變量; 唯一可以保持不變的人就是 ,因此甚至不要嘗試依賴編譯器為您完成此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM