2013-01-18 54 views
3

我有一個通用的方法具有以下簽名:數組類型的調用泛型方法

Broker.GetMessages<TType>(); 

它可以通過以下方式來使用:

IList<IEmailMessage> emails = Broker.GetMessages<IEmailMessage>(); 

我需要執行此方法在這種結構的陣列中可用的一系列類型:

var messageTypes = new [] { typeof(IEmailMessage), typeof(IFaxMessage) } 

我的最終結果應該是這樣的:

foreach (IMessage message in messageTypes) 
{ 
    Broker.GetMessages<xxx>(); 
} 

問題是我不知道如何隱藏類型爲了通過它作爲一個通用的。我知道我可以使用反射來調用該方法,但我想知道是否有更好的方法來實現這一點。 我可以更改數組結構,但不能更改方法簽名。

+0

你的最後一個碼聲明實際上是的foreach(在messageTypes類型消息)。無論如何,爲了這個你想做的事情,我不會選擇一個泛型方法,而是一個常規方法(輸入messageType)作爲輸入參數。 – Matthias

+0

此方法的簽名應該更像是'Broker.GetMessages(Type messageType);'。我敢打賭你在這個方法裏面調用'typeof(TType)',這表明它不應該是通用的。 – Groo

+0

你根本沒有讀過這篇文章。我不能更改代理的簽名,因爲它是第三方程序集...... – Raffaeu

回答

5

不,您需要使用反射。你已經給出了一半的方法,你已經有了Type[] - 任何時候你使用typeof,你正在走向反思。泛型適用於在編譯時知道類型的情況 - 儘管您已將這些類型硬編碼到messageTypes數組中,但您仍然從調用方法中斷開編譯時知識類型。

這是相當簡單的做到這一點:

var definition = typeof(Broker).GetMethod("GetMessages"); 
var generic = definition.MakeGenericMethod(type); 
var result = generic.Invoke(null); 
+0

雖然調用makeGenericMethod的代價很高,因爲它使用反射。如果不是這樣,我會讓它工作 – Raffaeu

+1

@Raffaeu:我不知道它有多昂貴,但是你應該先得到代碼,然後檢查成本。如果你真的想要,你可以按類型緩存'MakeGenericMethod'的結果,但是我不會增加複雜度,直到我有* data *來表明它是必需的。 –

+0

感謝您的建議,我會嘗試讓我的測試健身運作,然後看看它是多麼昂貴 – Raffaeu