如果我有一个用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
才能清楚并能够超载。但是很明显,rst
和arg
必须是int
。为什么我必须定义所有这些? CS0748告诉我不要这样做,但是没有原因。
在我看来,这应该是这样。是否有任何异常可能导致此问题?
D<int, int> d1 = ( arg, out rst) => {...} ////won't compile
更新
C#设计小组仍在讨论此问题。官方C#语言设计库#338中有很多有关此未解决问题的建议。
答案 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(
隐式匿名函数参数
隐式匿名函数参数列表:
隐式匿名函数参数
隐式匿名函数参数列表
)
隐式匿名函数参数隐式匿名函数参数:
- 标识符