这三个代表声明之间有什么区别?

时间:2017-04-18 14:37:40

标签: c# delegates

假设有以下代表:

delegate int Foo(int x);

我见过人们以多种方式创建这个委托,例如:

示例1:

Foo f = Bar;

Bar

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

示例2:

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

示例3:

Foo f = x => x * 2;

除了个人编码风格偏好之外,是否存在任何差异(专业,合作,效率等)?

3 个答案:

答案 0 :(得分:1)

虽然示例2和3几乎完全相同,但当用作本地声明时,这两个示例可能与示例1不同。

2和3之间没有区别:在2中,您明确指定委托类型,而在第二种情况下,您让编译器通过查看f的类型来确定委托的类型。当f是局部变量时,您可以进一步简化声明

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

以便Foo只指定一次。

第一个示例使用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仅限于使用您传递的x以及声明Bar的对象的任何字段。

因此,在决定这三个选项时,您需要考虑以下几点:

  • 如果您需要一个不关闭局部变量的委托,并且依赖于可以在别处使用的逻辑,请使用方法组,
  • 如果您需要一个关闭局部变量的委托,请使用2 var或3,
  • 如果要声明字段,请使用3,因为您必须始终指定字段的类型。

答案 1 :(得分:0)

主要区别在于,在示例1中,您可以重用功能栏。我相信2和3是同义词,lambda表达式只是匿名函数的语法糖。

答案 2 :(得分:0)

下面的第一个示例名为expression bodied method,因此委托将引用此方法,该方法返回int并将x的任何值乘以2并将其乘以{{ 1}}。

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

下面的第二个示例是使用lambda expression,它正在实例化委托并传递对该方法的引用,该方法将返回x乘以2的值。

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

最后一个例子就是语法糖,它在幕后与上面的例子非常相似。

Foo f = x => x * 2;
  

除了之外是否存在任何差异(职业选手,比赛,效率等)   个人编码风格偏好?

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