2017-04-18 137 views
1

假設有以下代表:這三個委託聲明有什麼區別?

delegate int Foo(int x); 

我見過的人創建委託以多種方式,例如:

例1:

Foo f = Bar; 

隨着酒吧正在:

int Bar(int x) => x * 2; 

例2:

Foo f = new Foo(x => x * 2); 

例3:

Foo f = x => x * 2; 

有什麼不同(親的,反對的,效率等)比個人編碼風格偏好等?

+0

請參閱[代表(C#編程指南)](https://msdn.microsoft.com/en-us/library/ms173171.aspx)。 – Romoku

+0

也許如果我將這個問題改寫爲更多關於正在生成的MSIL代碼的話,那麼它似乎就不那麼重要了。 – Timmeh

+0

@dasblinkenlight你指的是什麼*這種差異? – HimBromBeere

回答

1

雖然示例2和3幾乎完全相同,但在用作本地聲明時,這兩者可能與示例1不同。

2和3之間沒有區別:在2中,顯式指定委託類型,而在第二種情況下,讓編譯器通過查看f的類型來確定委託的類型。當f是一個局部變量,就可以使指定只有一次Foo進一步簡化申報

var f = new Foo(x => x * 2); 

第一個示例使用lambda-bodied方法通過方法組定義委託。這裏明顯的區別是這種聲明委託的方式需要一個單獨的方法。

但是,這裏還有一個細微的區別:當來自例子2和3的委託在本地上下文中使用時,它們可以關閉局部變量。相比之下,即使您在本地環境中使用它,示例1也不能捕獲局部變量。

代碼實施例2和3讓你這樣做:

Foo Make(int y) { 
    var res = x => x * y; // y is captured from the context 
    return res; 
} 

而實施例1是限於使用您傳遞和聲明Bar所述對象的任何字段x

因此,你需要考慮以下幾點這三個選項中作出決定時:

  • 如果你需要一個委託,它不會關閉在局部變量,並依賴於可以在其他地方使用的邏輯,使用方法組,
  • 如果您需要關閉在局部變量的委託,使用2 var,或3,
  • 如果要聲明一個字段,使用3,因爲你必須反正指定字段的類型。
+0

就像你用var聲明的那樣(但也包括例如匿名對象),你不能明確地使用方法3('(Foo)(x => x * 2)'),在我看來,這將需要一個額外的操作。所以我想方法2在某些場合會比方法3更好? – Timmeh

+0

@Timmeh'Foo(x => x * 2)'肯定比'((Foo)(x => x * 2))'好。方法3在字段聲明(與本地聲明相對)的上下文中很好,因爲你必須明確指定類型,即沒有選項可以使用'var'。 – dasblinkenlight

0

主要區別在於,在示例1中,您可以重用您的功能欄。我相信2和3是同義詞,lambda表達式只是匿名函數的語法糖。

0

第一,下面的實施例被稱爲expression bodied method,所以代表將參考此方法,它返回一個int和將採取任何的x值,並通過2相乘。

int Bar(int x) => x * 2; 

第二,下面的示例是使用lambda expression,它被實例化委託並傳遞一個參考,將返回的x乘以2的值的方法。

Foo f = new Foo(x => x * 2); 

最後一個例子僅僅是語法糖,它在幕後幾乎與上面的例子相同。

Foo f = x => x * 2; 

有什麼不同(親的,反對的,效率等)以外 個人編碼風格偏好?

它們都基本完成相同的最終結果,但是,第一個示例可以多次重複使用該方法,而最後兩個要傳遞的行爲只是在稍後執行(稍後時間)沒有任何標識符以供以後重用。