2010-04-25 65 views
1

有時候最簡單的問題讓我更喜歡C/C++和C#。非常簡單的代表沉思

今天坐在公交車上的思考代表我記得 閱讀somwhere你不需要使用新的關鍵字時,instinoating 新的代表。

例如:

public static void SomeMethod(string message) 
    { 
     ... 
    } 

    ... 


    public delegate void TestDelgate(string message); //Define a delegate 

    ........... 

    //create a new instance ..METHOD 1 
    TestDelgate t = new TestDelgate(SomeMethod); 

    //OR another way to create a new instance ..METHOD 2 
    TestDelgate t = SomeMethod; //create a new instance ..METHOD 2 

所以今天的問題是

  1. 引擎蓋下發生在方法2是什麼編譯器展開方法2成方法1,因此,寫TestDelgate噸=的someMethod ;僅僅是 TestDelgate T =新TestDelgate(的someMethod)的快捷方式;,或者是有其他原因的方法的exsitence 2

  2. 你們認爲方法1或方法2是可讀性更好(這是一個主觀的的問題,但我只是想獲得計算器:-)的一般看法的不科學的感覺)

+1

相關問題:http://stackoverflow.com/questions/550703/c-difference-between-anevent-and-new-eventhandleranevent/550708#550708 – driis 2010-04-25 20:06:56

回答

1

它是糖。當你必須寫下這些糖真的很方便:

someObj.Test -= new TestDelegate(SomeMethod); 

什麼?您必須使用新的關鍵字刪除事件處理程序。是的你是。在VB.NET團隊真的心疼這個,他們決定一個完全不同的語法:

RemoveHandler someObj.Test, AddressOf SomeMethod 


即使上述C#語句是糖,真正的代碼如下所示:

someObj.Test.remove(new TestDelegate(this, SomeMethod)); 

在哪裏「remove」是事件的訪問器函數。並且需要「this」來初始化Delegate.Target屬性。現在很明顯,它實際上是一個方法調用,並且使用new關鍵字突然變得有意義。隱藏「this」也有一些缺點,事件訂閱將不會阻止對象被垃圾收集。

1
  1. 是的,他們被編譯成同樣的事情。

  2. 我更喜歡#2。只是因爲它更短,並不笨拙。你已經知道它是一個TestDelegate,因爲之前定義了它。那麼爲什麼要再寫一遍?

2

底下,你的2種方法是完全一樣的。只是編譯器對你想要做的事情很聰明。這個小功能被稱爲delegate inference,並添加到C#2.0中。

我認爲你應該使用#2,並利用委託推理。它們編譯爲相同的IL,而選項#2更短且更簡潔。閱讀和理解代碼的含義比較容易,因爲噪音較少。

此語法爲also supported for events

0

在引擎蓋下,兩個語句創建委託對象並將參數傳遞給ctor:方法的地址和對此的引用。其次是語法糖。

4

是的,方法2只是方法1的簡寫 - 至少在使用方法組的情況下。您可以使用:

TestDelegate t = new TestDelegate(someExistingDelegate); 

它允許偏差(不只是從C#4中的通用方差),並創建一個單獨的委託......但那是很少有用。

就我個人而言,我會選擇2 ...方法組轉換非常方便。特別是它使事件接線簡單:的

button.Click += LoadDocument; 

代替

button.Click += new EventHander(LoadDocument); 

後者只是有額外的絨毛 - 前者具有更好的信息密度。將代理作爲方法參數傳遞時也很重要。例如,比較:

observable.Subscribe(new Action<string>(Console.WriteLine)); 

observable.Subscribe(Console.WriteLine); 

除非有其委託類型的你真的想方法組轉換,我只使用隱式轉換條款有任何含糊。

1
  1. 這只是顯式委託創建的合成糖。這是C#2.0中的introduced。您可能已經注意到,如果您要求它創建一個事件處理程序,Visual Studio 2008仍會生成舊式(方法1)語法;我總是用新的語法手動替換它。

  2. 我通常更喜歡方法2中的較短形式。我僅使用方法1一次:使用從本機代碼調用的委託,因此無法進行垃圾回收。我想對創建和分配它非常明確。

0

'new'語法的一個優點是它通知程序員一個新的對象被分配;如果希望避免重複創建新的相同代表,可以將代表拖出現場。我知道,實際上允許一個代表使用一個代表來訂閱,另一個代表退訂,但對於我來說,這感覺不對。存儲到代理用於訂閱的字段,然後取消訂閱使用相同的代理感覺更清潔。如果訂閱行爲會返回一個MethodInvoker,當被調用的時候,它會退訂(在這種情況下,「事件」只是一個接受EventHandler並返回一個MethodInvoker的函數),但是這仍然是恕我直言,不是.net事件如何工作。