2008-11-28 60 views
107

編輯:調用只有在執行時間已知類型參數的泛型方法

當然,我真正的代碼看起來不像這樣。我試着編寫半僞代碼,使它更清楚我想做的事情。

看起來它只是搞砸了事情。

所以,我其實想這樣做是這樣的:

Method<Interface1>(); 
Method<Interface2>(); 
Method<Interface3>(); 
... 

嗯......我想,也許我可以使用反射把它變成一個循環。所以問題是:我該怎麼做。我有非常的淺層知識的反思。所以代碼示例會很棒。

的情況是這樣的:

public void Method<T>() where T : class 
{} 
public void AnotherMethod() 
{ 
    Assembly assembly = Assembly.GetExecutingAssembly(); 

    var interfaces = from i in assembly.GetTypes() 
    where i.Namespace == "MyNamespace.Interface" // only interfaces stored here 
    select i; 

    foreach(var i in interfaces) 
    { 
     Method<i>(); // Get compile error here! 
    } 




原帖:

嗨!

我通過所有接口試圖環路命名空間並將它們作爲參數傳遞給這樣的泛型方法:

public void Method<T>() where T : class 
{} 
public void AnotherMethod() 
{ 
    Assembly assembly = Assembly.GetExecutingAssembly(); 

    var interfaces = from i in assembly.GetTypes() 
    where i.Namespace == "MyNamespace.Interface" // only interfaces stored here 
    select i; 

    foreach(var interface in interfaces) 
    { 
     Method<interface>(); // Get compile error here! 
    } 
} 

我得到的錯誤是「類型名稱,但局部變量名中」。 如果我嘗試

... 
    foreach(var interface in interfaces) 
    { 
     Method<interface.MakeGenericType()>(); // Still get compile error here! 
    } 
} 

我得到「無法應用運營商「<爲鍵入‘法團’和‘的System.Type’的操作數」 如何解決這個問題的任何想法?

回答

133

編輯:好的,時間短但完整的程序。最基本的答案是像以前一樣:

  • 與Type.GetMethod
  • 找到「打開」通用方法
  • 使用MakeGenericMethod
  • 使它通用與調用,調用它

下面是一些示例代碼。請注意,我將查詢表達式更改爲點符號 - 當您基本上只有一個where子句時,使用查詢表達式沒有意義。

using System; 
using System.Linq; 
using System.Reflection; 

namespace Interfaces 
{ 
    interface IFoo {} 
    interface IBar {} 
    interface IBaz {} 
} 

public class Test 
{ 
    public static void CallMe<T>() 
    { 
     Console.WriteLine("typeof(T): {0}", typeof(T)); 
    } 

    static void Main() 
    { 
     MethodInfo method = typeof(Test).GetMethod("CallMe"); 

     var types = typeof(Test).Assembly.GetTypes() 
           .Where(t => t.Namespace == "Interfaces"); 

     foreach (Type type in types) 
     { 
      MethodInfo genericMethod = method.MakeGenericMethod(type); 
      genericMethod.Invoke(null, null); // No target, no arguments 
     } 
    } 
} 

原來的答覆

讓我們撇開調用變量「接口」下手的突出問題。

你必須通過反思來調用它。泛型的要點是在編譯時間進行更多的類型檢查。編譯時你不知道類型是什麼 - 因此你必須使用泛型。

獲取泛型方法,並調用MakeGenericMethod,然後調用它。

您的接口類型本身實際上是通用的嗎?我問,因爲你在它調用MakeGenericType,但不通過任何類型的參數......你是不是想叫

Method<MyNamespace.Interface<string>>(); // (Or whatever instead of string) 

Method<MyNamespace.Interface>(); 

如果是後者,你只需要一個調用MakeGenericMethod - 不是MakeGenericType。

+0

我想存根據類型的泛型方法。但是,如果我使用反射來製作它,然後對生成的一個進行存根,它就會明白它不會殘留我想要的。 我的猜測是這是不可能的?或者是? 在一個列表中存在所有類型的通用方法...... – 2010-12-09 10:41:37

相關問題