为什么我必须在lambda表达式中用out / ref显式定义所有类型?

时间:2019-02-20 05:42:16

标签: c# lambda

如果我有一个用out关键字定义的委托,例如:

delegate int D<TResult, TArgument>(TArgument argument, out TResult result);

我想使用lambda表达式进行设置,它必须像这样:

        D<int, int> d = (int arg, out int rst) =>{...} //correct

以下两个陈述是错误

        D<int, int> d1 = ( arg, out rst) => {...} //CS2046

        D<int, int> d2 = (arg, out int rst) => {...} //CS0748

所以我的问题是:为什么C#这样设计?我了解您必须声明out才能清楚并能够超载。但是很明显,rstarg必须是int。为什么我必须定义所有这些? CS0748告诉我不要这样做,但是没有原因。

在我看来,这应该是这样。是否有任何异常可能导致此问题?

D<int, int> d1 = ( arg, out rst) => {...} ////won't compile

更新

C#设计小组仍在讨论此问题。官方C#语言设计库#338中有很多有关此未解决问题的建议。

1 个答案:

答案 0 :(得分:3)

C#语言的设计者似乎认为严格地可以存在两种类型的匿名函数签名-分别定义为显式匿名函数签名隐式-匿名功能签名

explicit-anonymous-function-signature 是一个相当标准的参数列表-在()括号之间并用逗号分隔,每个参数定义都包含一个可选的修饰符({{1 }}或out),类型和标识符。

隐式匿名功能签名是一个非常简单的参数列表-在ref括号之间并用逗号分隔,每个参数定义仅包含一个标识符。

您不必在两种形式之间进行混搭,而必须选择其中一种。这可能使解析变得更简单,并使类型推断成为一种开/关概念,而不是“半开”的概念(()的意思就是这样)。

通过谈论具有一种或另一种签名类型的lambda,肯定可以使他们使语言中的其他规则更易于指定。

因此,如果您需要包含修饰符(CS0748),则别无选择-必须使用 explicit-anonymous-function-signature


根据C#规范第5版:

  

lambda表达式

     
      
  • 匿名功能签名 out 匿名功能主体
  •   
     

匿名方法表达式

     
      
  • => 显式匿名功能签名 opt block
  •   
     

匿名功能签名

     
      
  • 显式匿名功能签名

  •   
  • 隐式匿名功能签名

  •   
     

显式匿名功能签名

     
      
  • delegate 显式匿名函数参数列表 opt (
  •   
     

显式匿名函数参数列表

     
      
  • 显式匿名函数参数

  •   
  • 显式匿名函数参数列表 ) 显式匿名函数参数

  •   
     

显式匿名函数参数

     
      
  • 匿名函数参数修饰符 opt 类型 标识符
  •   
     

匿名函数参数修饰符

     
      
  • ,

  •   
  • ref

  •   
     

隐式匿名功能签名

     
      
  • out 隐式匿名函数参数列表 opt (

  •   
  • 隐式匿名函数参数

  •   
     

隐式匿名函数参数列表

     
      
  • 隐式匿名函数参数

  •   
  • 隐式匿名函数参数列表 ) 隐式匿名函数参数

  •   
     

隐式匿名函数参数

     
      
  • 标识符
  •