2011-03-22 121 views
8

是否有存儲的委託不綁定到一個對象怎麼樣,你可以用一個MethodInfo的一種方式?現在我正在存儲一個MethodInfo,所以我可以給它一個調用該方法的對象。但我更希望它是一個代表。就像有一個屬性告訴.net第一個參數是「this」?C#委託沒有綁定到實例?

MethodInfo mi; 
Action<string> func; 
mi.Invoke(this,new object[]{str}); 
func(this, str); //Is this possible with a delegate? 
+0

你可以改一下用多一點的細節問題,我想我懂了部分但不當然。 – 2011-03-22 23:52:14

+0

增加了我的意思的例子。基本上有可能有一個委託沒有對象引用,並給它一個對象,當你打電話給它? – Will 2011-03-23 00:06:18

+1

我改變了你的問題的標題,使其更清晰。隨意回滾,如果你不喜歡它;) – 2011-03-23 00:14:08

回答

11

你想要什麼叫做open instance delegate。它不直接支持C#語言,但CLR支持它。

基本上,打開的實例委託與普通委託相同,但它在普通參數之前需要this的額外參數,並且具有空目標(如靜態方法的委託)。例如,打開實例相當於Action<T>是:

delegate void OpenAction<TThis, T>(TThis @this, T arg); 

這裏有一個完整的例子:

void Main() 
{ 
    MethodInfo sayHelloMethod = typeof(Person).GetMethod("SayHello"); 
    OpenAction<Person, string> action = 
     (OpenAction<Person, string>) 
      Delegate.CreateDelegate(
       typeof(OpenAction<Person, string>), 
       null, 
       sayHelloMethod); 

    Person joe = new Person { Name = "Joe" }; 
    action(joe, "Jack"); // Prints "Hello Jack, my name is Joe" 
} 

delegate void OpenAction<TThis, T>(TThis @this, T arg); 

class Person 
{ 
    public string Name { get; set; } 

    public void SayHello(string name) 
    { 
     Console.WriteLine ("Hi {0}, my name is {1}", name, this.Name); 
    } 
} 

看一看this article瞭解更多詳情。

+0

C#不直接支持它。感謝您的信息:D。 – Will 2011-03-23 00:26:08

5

可以使用Delegate.CreateDelegate方法來創建一個強類型的代表爲MethodInfo

如果你不知道方法的在編譯時簽名,你可以創建一個Func<...>使用反射,或創建調用MethodInfo lambda表達式:

MethodInfo methodInfo = ...; 
object thisObj = ...; 
Func<object[]> callMethod = args => methodInfo.Invoke(thisObj, args); 

(這就是所謂的鑽營)

注意,這將仍然具有反射每個委託被調用時命中的表現,不像Delegate.CreateDelegate

+0

沒有考慮使用lambda使它更好,謝謝。 – Will 2011-03-23 00:22:34

0

委託實質上只是一個MethodInfo(實際上,一個MethodBase)和一個對象引用,其中有一些內部指針用於執行。所以,如果你有一個MethodInfo,你實際上有一個未綁定的委託。你的具體用例是什麼?

+1

在功能上,是的,它大致相同。但是MethodInfo.Invoke比調用代表... – 2011-03-23 00:15:21

+0

@Thomas Levesque的要慢得多:授予。對於重複呼叫,可以通過調用「委託」來改善性能。CreateDelegate()'來創建一個綁定的委託,但是我猜想對於綁定調用放棄綁定調用放棄模式,它不會提供任何性能優勢。 – 2011-03-23 02:05:52

0

爲什麼不乾脆

Action<T, string> unbound = (This, str) => This.Method(str); 

這樣你就可以

unbound(instanceA, "hello"); 
unbound(instanceB, "world"); 

甚至

Action<string> bound = str => unbound(instanceC, str);