使用 lambda 表达式和匿名函数时出现错误和警告

与声明和使用 lambda 表达式相关的几个 错误

  • CS0748lambda 参数用法不一致;参数类型必须是全部显式或全部隐式的。
  • CS1621yield 语句不能在匿名方法或 lambda 表达式中使用。
  • CS1628不能在匿名方法、lambda 表达式或查询表达式中使用 inrefout 参数。
  • CS1632控制不能离开匿名方法或 lambda 表达式的正文。
  • CS1673结构内的匿名方法、lambda 表达式和查询表达式无法访问“this”的实例成员。
  • CS1686局部变量或其成员无法获取其地址,并且不能在匿名方法或 lambda 表达式中使用。
  • CS1706表达式不能包含匿名方法或 lambda 表达式。
  • CS8030转换为 void 返回委托的匿名函数无法返回值。
  • CS8175无法在匿名方法、lambda 表达式或查询表达式中使用 ref local。
  • CS8916lambda 表达式的属性需要带括号的参数列表。
  • CS8971在应用于 lambda 参数时,InterpolatedStringHandlerArgument 不起作用,将在调用站点被忽略。
  • CS8975上下文关键字 var 不能用作显式 lambda 返回类型。
  • CS9098隐式类型 lambda 参数“...”不能有默认值。

此外,还有一些与声明和使用 lambda 表达式相关的 警告

  • CS8971在应用于 lambda 参数时,InterpolatedStringHandlerArgument 不起作用,将在调用站点被忽略。
  • CS9099默认参数值与目标委托类型不匹配。
  • CS9100参数在 lambda 中具有参数修饰符,但在目标委托类型中没有参数修饰符。

编译器还会生成以下 信息性 消息:

  • CS9236编译需要至少绑定 lambda 表达式的计数时间。考虑使用显式参数类型声明 lambda 表达式,或者如果包含的方法调用是泛型的,请考虑使用显式类型参数。

lambda 表达式中的语法限制

lambda 表达式和匿名方法中禁止某些 C# 语法。 在 lambda 表达式中使用无效构造会导致以下错误:

  • CS1621语句 yield 不能在匿名方法或 lambda 表达式中使用。
  • CS1628不能在匿名方法、lambda 表达式或查询表达式中使用inrefout参数。
  • CS1632控制不能离开匿名方法或 lambda 表达式的正文。
  • CS1673结构内的匿名方法、lambda 表达式和查询表达式无法访问实例 this成员。
  • CS1686局部变量或其成员无法获取其地址,并且不能在匿名方法或 lambda 表达式中使用。
  • CS8175无法在匿名方法、lambda 表达式或查询表达式中使用 ref local。

lambda 表达式中不允许使用以下所有构造:

  • yield 语句(yield returnyield break
  • 调用具有 inrefout 参数的方法
  • ref 局部变量
  • breakgotocontinue 语句
  • this访问,当thisstruct类型时
  • 其他表达式中的匿名方法或 lambda 表达式,例如 Attribute 构造函数。

不能在 lambda 表达式或匿名方法中使用上述任何构造。 许多函数都允许在本地 函数中使用。

此外,当应用于 lambda 参数时,将忽略内插字符串处理程序类型。 如果使用一个,会看到以下警告:

  • CS8971在应用于 lambda 参数时,InterpolatedStringHandlerArgument 不起作用,将在调用站点被忽略。

某些表达式导致编译器发出以下信息警告:

  • CS9236编译需要至少绑定 lambda 表达式计数次。考虑使用显式参数类型声明 lambda 表达式,或者如果包含的方法调用是泛型的,请考虑使用显式类型参数。

lambda 表达式的复杂性以及它们调用其他 lambda 表达式的方式对编译器性能产生负面影响。 原因是编译器必须通过 lambda 表达式推断参数和参数类型,并且潜在类型需要时间。

Lambda 表达式参数和返回

这些错误表示参数声明存在问题:

  • CS0748lambda 参数用法不一致;参数类型必须是全部显式或全部隐式的。
  • CS9098隐式类型 lambda 参数“...”不能有默认值。
  • CS8030转换为 void 返回委托的匿名函数无法返回值。
  • CS8916lambda 表达式的属性需要带括号的参数列表。
  • CS8975上下文关键字“var”不能用作显式 lambda 返回类型。

Lambda 表达式参数必须遵循以下规则:

  • 当 lambda 表达式具有多个参数时,必须显式键入所有参数,或者必须隐式键入所有参数。
  • 具有默认值的所有 lambda 参数都必须显式类型化。
  • 如果属性应用于任何参数,则必须将参数列表括在括号中。

lambda 表达式的返回类型必须遵循以下规则:

  • 返回任何值的 lambda 表达式无法转换为 void 返回委托,例如 Action
  • 返回类型是推断的,还是显式类型。 不允许使用关键字 var 声明的返回类型。

Lambda 表达式委托类型

  • CS9099:警告: 默认参数值与目标委托类型不匹配。

当您用 lambda 表达式参数声明默认值或添加 params 修饰符时,委托类型不是 Func 类型或 Action 类型中的任何一种。 而是包含默认参数值或 params 修饰符的自定义类型。 以下代码生成警告,因为它将具有默认参数的 lambda 表达式分配给类型 Action

Action<int> a1 = (int i = 2) => { };
Action<string[]> a3 = (params string[] s) => { };

若要修复此错误,请删除默认参数,或使用委托类型的隐式类型变量:

Action<int> a1 = (int i) => { };
var a2 = (int i = 2) => { };
Action<string[]> a3 = (string[] s) => { };
var a4 = (params string[] s) => { };