簡體   English   中英

使用泛型問題並使用運行時類型,而不是(通用)T

[英]Issue with Generics and using a run-time Type, rather than (generic) T

為了盡可能容易地解決問題,我試圖實現一個通用池系統,只要它們實現IBaseComponent就可以處理任意數量的具體類。

所以,在我管理池的類中,我有一個Pool of Dictionarys:

Dictionary<Type, Pool<IBaseComponent>> pools;

因為這將允許我創建盡可能多的實現IBaseComponent類(這是一個非常“低級別”的接口,所以可以這么說 - 所以實現它的類不會兼容得太多),並且可以有每個人都有一個游泳池

現在,我正在運行的問題是第一次將IBaseComponent加載到池中,充當模板,可以這么說。

這個模板對象是從XML而不是代碼加載的,所以我在編譯時沒有它的實際 ,只在運行時(它在XML定義中定義,我通過反射獲取正式的Type)。 這一切都很好,但是,正如我們所知,泛型依賴於編譯時的安全性。

所以,使用一些反思技巧,我有以下內容:

var type = typeof(MyChildComponent);
var genericType = typeof(Pool<>);
var specificType = genericType.MakeGenericType(type);
var pool = Activator.CreateInstance(specificType );

pools.Add(T, pool as Pool<IBaseComponent>);

假設一些課:

public class MyChildComponent : IBaseComponent

當我添加到池字典時,問題出現在第一個塊的最后一行。 實例化池到Pool<IBaseComponent>失敗,導致將null插入到Dictionary中。

我對你這些好人的問題是:有什么合理的方法嗎? 任何可能的方式,甚至是?

如果我需要加載通過一些外部方法(XML,TXT,等等),至少在第一個模板對象為池,該池可用於每個可能的具體類, 我有機會要素是頂級接口和正式類的類型(都在外部定義文件中定義),我可以在這做任何事情嗎?

或者根本不可能這樣做?

你在使用.Net 4+嗎? 如果是這樣,您可以創建一個接口IPool<out T> out使得泛型參數協變,這意味着它將接受任何版本的接口,其泛型參數為T或從T派生。

由於某種原因,協同/反演只適用於接口和委托,這就是你需要IPool的原因。

你的詞典將成為:

Dictionary<Type, IPool<IBaseComponent>>() pools;

我把它與我的頭腦中的反射結合起來有點麻煩,但我認為這應該有效。 如果沒有,請告訴我,我會花更多時間在我的測試代碼上。

我正在考慮的另一個選擇是修改Pool<T>本身。

而不是讓Pool<T>只存儲一種類型的(concerete)類,我將修改它以支持基於用於T的接口存儲任何兼容的類。

因此, Pool<IBaseComponent>將負責存儲實現IBaseComponent所有可能類型。

在內部 ,它會將所有內容存儲為IBaseComponent ,但會保留對每個具體類型存儲位置的引用(在Type的列表,可能,甚至只是一個大的線性列表[雖然這會調整“池”的大小)對於特定類型更復雜])

我忽略了一件事,就是IBaseComponent公開了兩個功能點,這些功能都是我准備以“盲”方式使用的組件所需要的(即:調用此池的工廠在編譯時不知道什么它正在使用的組件類型,它只是根據XML中定義的內容加載它們,或者從附加了這些組件的現有對象進行復制),即: Deserialize (從XML / JSON構建組件/無論如何)和CopyInto(IBaseComponent other) (通過從另一個組件復制來構建組件)。

因此,這仍然存在Pool無法將IBaseComponent動態IBaseComponent為調用者請求的Type ,但這無關緊要。 如果調用者真的提前知道硬編譯時類型 ,它可以進行強制轉換 如果調用者沒有,那么除了IBaseComponent公開的訪問方法之外,它將無法做任何事情。

重要的是, Pool返回的IBaseComponent是正確的類型,這將處理。

簡單地說:我將刪除一些現代泛型(從某種程度上說,Pool只適用於傳入的類型,外部它只允許T成為一個接口),並且替換它將很好地傳遞Type 必須在內部使用反射來實例化類型池,但我認為可以預期初始化或調整池的大小將是非常昂貴的。

暫無
暫無

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

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