2013-06-13 59 views
3

我是C#的新手,有兩個關於delegate s的問題。代表問題

MSDN表明Delegate類只有兩個構造函數,它們每個都有兩個參數。但是,在下面的程序中,我使用看似單參數的構造函數實例化了一個Delegate對象(請參閱註釋行)。

using System; 

static class Program 
{ 
    public delegate void MyDelegate(); 

    static void MyMethod() 
    { 
     Console.WriteLine("I'm inside MyMethod!"); 
    } 

    static void Main() 
    { 
     MyDelegate myDelegate = new MyDelegate(MyMethod); // Constructor Call 
     myDelegate(); 
    } 
} 

我誤解了什麼嗎?

我的第二個問題是:當用一個或多個參數聲明delegate時,爲什麼我們需要給參數名稱?在C++中,我們可以做這樣的事情在類:

public delegate void MyOtherDelegate(int, int, string); 
+3

如果你有兩個問題,然後開始*兩個*問題。否則,你最終會遇到一些人回答一個人而另一些人回答另一個人的問題,然後哪個人成爲所選擇的答案?一團糟。通過每個問題詢問一個問題來避免這種情況。 –

+0

一位語言設計師非常清楚歧義的複雜性:) @EricLippert – nawfal

回答

2

它可能看起來像你調用一個標準的構造函數,但C#編譯器實際上對你的代碼做了一點小小的修改。當你寫

MyDelegate myDelegate = new MyDelegate(MyMethod); 

你實際上沒有直接調用MSDN上列出的任何構造函數。它改爲調用編譯器自動在代理類型MyDelegate上定義的構造函數(這些構造函數未在MSDN上顯示)。實際上,MSDN上列出的構造函數甚至不能直接調用:

此構造方法不能在應用程序代碼中使用。要通過指定實例方法的名稱來創建委託,請使用CreateDelegate方法的重載…

值得一提的是,你甚至可以爲了簡潔做到這一點:

MyDelegate myDelegate = MyMethod; 

至於爲什麼參數名是必要的,也許他們可能不是絕對必要的,一般的編譯,但我懷疑CLR的設計人員希望與運行時的其他功能保持一致。它可以讓你做的事情,如指定明確的參數名稱,你就無法不這樣做:

Func<int, int> foo = x => x + 1; 
foo(arg: 1); 

這也意味着你可以通過反射檢查參數名稱和可能與他們做一些有用的處理。

1

不完全回答你的問題,但只是讓你知道,C#還支持Func鍵代表。在這種情況下,你甚至不需要聲明任何東西。

例如此方法接受委託類型爲String的參數和輸出詮釋

public static void DoSomethingWithDelegate(Func<string, Int32> converstionDelegate) 
{ 
    int x = converstionDelegate("1"); 
} 

瞭解更多關於在這裏:​​http://msdn.microsoft.com/en-us/library/bb549151.aspx