2010-03-12 94 views
2

我不知道C#(或底層的.NET框架)是否支持某種「通用委託實例」:這是一個委託實例,它仍然有一個未解析的類型參數,在代理被解析時被調用(不是在創建委託時)。我懷疑這是不可能的,但我仍然要求它...通用委託實例

這是我想要做的一個例子,用一些「???」插入C#語法似乎不可用的地方。 (顯然這個代碼不能編譯)

class Foo { 
    public T Factory<T>(string name) { 
    // implementation omitted 
    } 
} 

class Test { 
    public void TestMethod() 
    { 
    Foo foo = new Foo(); 
    ??? magic = foo.Factory; // No type argument given here yet to Factory! 
          // What would the '???' be here (other than 'var' :))? 
    string aString = magic<string>("name 1"); // type provided on call 
    int anInt = magic<int>("name 2"); // another type provided on another call 

    // Note the underlying calls work perfectly fine, these work, but i'd like to expose 
    // the generic method as a delegate. 
    string aString2 = foo.Factory<string>("name 1"); 
    int anInt2 = foo.Factory<int>("name 2"); 
    } 
} 

有沒有一種方法可以在C#中實際執行此類操作?如果沒有,這是語言的限制,還是在.NET框架?

編輯: 我想問的原因是因爲我想委託傳遞給函數在其他組件,並且不希望要求不必引用任何特定類型的其他組件(以下簡稱「富「在我的例子中的類)。我希望以某種方式彎曲標準Func <>委託,以適應「???」部分。

+0

C#也知道這個詞var和將得到的構建類型。 – Younes 2010-03-12 10:44:11

+0

你知道你可以foo.Factory (「名字1」),我想。你能否擴展你的問題來解釋爲什麼你需要使用魔術而不是foo.Factory ? – 2010-03-12 10:48:51

+0

你也可以寫'對象':)。 object magic = foo.Factory; – 2010-03-12 10:54:35

回答

7

這是無法完成的,因爲您要求的是聲明非封閉泛型類型的變量(magic)。

人們可以用不封閉的仿製藥,但只有在類型級別的工作,如:

delegate T FactoryDelegate<T>(string name); 

var magicType = typeof (FactoryDelegate<>); 

,然後「關閉」在稍後的類型:

var stringMagic = magicType.MakeGenericType(typeof(string)); 

更新:那說,這裏是一個關於如何使用上述技術來處理未封閉的方法「類型」的示例。還不如優雅的,因爲這將是如果我們能夠分配雖然未封閉的類型..:

public class UnclosedMethod 
    { 
     private readonly MethodInfo _method; 

     public UnclosedMethod(Type type, string method) 
     { 
      _method = type.GetMethod(method); 
     } 

     public T Invoke<T>(string name) 
     { 
      var fact = _method.MakeGenericMethod(typeof(T)); 
      return (T)fact.Invoke(this, new object[] { name }); 
     } 
    } 

然後在代碼中做到這一點:

var magic = new UnclosedMethod(typeof(Foo), "Factory"); 
var x = magic.Invoke<string>("bar"); 
+0

感謝您的回答,我已經懷疑過這樣的事情。 這留下了第二部分的問題:「是C#語言的限制,還是它在.NET框架中」。 – 2010-03-12 10:58:20

0

就有點像?:

Foo foo = new Foo(); 
string aString = 
    foo.GetType().GetMethod("Factory").MakeGenericMethod(string) 
     .Invoke(foo, new object[] { "name 1" }); 
int anInt = 
    foo.GetType().GetMethod("Factory").MakeGenericMethod(int) 
     .Invoke(foo, new object[] { "name 2" }); 

現在,如果你想使用代表,你可能會得到類似的結果:

public delegate T FactoryDelegate<T>(string name); 

然後,您可以作出這樣一個電話:

public TestMethod1(FactoryDelegate<dynamic> factory) 
{ 
    object o = factory("name 3"); 
}