2017-04-18 120 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; 

有什么不同(亲的,反对的,效率等)以外 个人编码风格偏好?

它们都基本完成相同的最终结果,但是,第一个示例可以多次重复使用该方法,而最后两个要传递的行为只是在稍后执行(稍后时间)没有任何标识符以供以后重用。