2009-10-05 59 views
2

好吧,也許這個標題沒有多大意義,但這是交易。說我有多個類型約束的泛型方法,這本:C#:如何找到並創建滿足多種類型約束的實例

public static void DoSomethingAwesome<T>(T thing) 
    where T : IThing, IAwesome, IComparable<T> 
{ 
    ... 
} 

現在....我怎麼能,使用反射,創造的東​​西,我可以在那兒送?

如果它只是一個約束,我知道我能做到這一點是這樣的:

var types = assembly 
     .GetTypes() 
     .Where(typeof (IThing).IsAssignableFrom) 

foreach(var t in types) 
    DoSomethingAwesome((IThing) Activator.CreateInstance(t)); 

但是,不能真正轉換爲多個接口...如何在地球上我能解決這個問題?你可以說我非常這裏現在已經失去了:P

標題有那種長而複雜,因爲我不知道怎麼稱呼這一點,請提高,如果你能

回答

4

要添加到裏德和羅蘭的回答關於尋找合適的類型,請注意,您仍然無法鑄造調用DoSomethingAwesome,因爲你已經發現,編譯器沒有提供將實例化對象轉換爲多個接口的方法。你有兩個選擇:

  1. 創建一個新的接口 IAwesomeComparableThing這 從IThing,IAwesome和 IComparable的<牛逼>派生,有你 類型實現這一點,投地 這一點。

  2. 通過 反思,調用DoSomethingAwesome。要做到這一點,你會 需要得到一個MethodInfo爲 DoSomethingAwesome泛型方法, 然後調用 MethodInfo.MakeGenericMethod與 你喜歡的類型,實現所有三個 接口。

的實施例(2):

Type type = sometype; // For example found using reeds method 
MethodInfo mgeneric = typeof(Awesomeiser).GetMethod("DoSomethingAwesome"); 
MethodInfo mspecific = mgeneric.MakeGenericMethod(new [] { type }); 
mspecific.Invoke(null, new [] { type }); 
+0

我從裏德得到的類型? – Svish 2009-10-05 19:21:54

+0

對不起,我不想複製Reed和Loren關於如何找到合適類型的答案。我假設,使用其他答案,您可以找到合適的類型並實例化一個實例(使用Activator.CreateInstance)。然後將此類型傳遞給MakeGenericMethod,並將實例傳遞給Invoke。對不起,缺乏清晰度。 – itowlson 2009-10-05 19:32:28

+0

啊,想我現在明白了。但笏是米?它應該是通用的嗎? – Svish 2009-10-06 09:30:01

0

我猜有某些原因您不能做

var types = assembly 
.GetTypes() 
.Where(typeof (IThing).IsAssignableFrom && typeof (IAwesome).IsAssignableFrom)) 
+0

不處理IComparable的約束,雖然,這是最棘手的。 – 2009-10-05 19:04:14

+0

要實例化它們,請像在問題中一樣使用Activator.CreateInstance。那麼你有單獨的問題將它們傳遞給方法;我已經發布了一個討論這個問題的答案。 – itowlson 2009-10-05 19:21:02

+0

嗯,我可以,而且當然會那樣做,但那隻會找到那些類。我仍然會在實例化它們時遇到麻煩。 – Svish 2009-10-05 19:23:04

0

您需要一個可從所有約束中分配的類型。前兩個是容易的,但第三個是有點棘手:

// Using 
static bool IsIComparable(Type thing) 
    { 
     foreach (Type interfaceType in thing.GetInterfaces()) 
     { 
      if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IComparable<>)) 
      { 
       Type[] arguments = interfaceType.GetGenericArguments(); 
       if (arguments.Length == 1) 
       { 
        if (arguments[0] == thing) 
         return true; 
       } 
      } 
     } 
     return false; 
    } 


// This returns an enumerable of compatible types: 
var types = assembly.GetTypes().Where(t => 
    typeof(IThing).IsAssignableFrom(t) && 
    typeof(IAwesome).IsAssignableFrom(t) && 
    IsIComparable(t)); 
+0

就我所見,這也只是幫助我找到這些類型。沒有以我可以將它們發送到通用方法的方式實例化它們。'IsComparable'方法雖然看起來很有幫助,但是非常感謝你:) – Svish 2009-10-05 19:21:04

相關問題