调用 lambda 表达式而不将其分配给委托

Posted

技术标签:

【中文标题】调用 lambda 表达式而不将其分配给委托【英文标题】:Call lambda expression without asigned it to a delegate 【发布时间】:2021-10-18 09:36:23 【问题描述】:

javascript 中我们可以像这样创建一个箭头函数:

let square= (a) => a * a;

然后像这样直接调用 let :

square(1, 2); 

是否有使用 c# 执行类似操作的解决方案? 我试过了,但它给了我这个错误(无法推断委托类型)

var square = (x) => x * x;

【问题讨论】:

不,lambda 表达式本身没有类型。 你必须把Func<int, int>Func<double, double>甚至Func<decimal, decimal>Func<int, double>作为labda的类型:var是不够的:所有这些可能的类型都不能是(x) => x * x;推断 除了其他人提到的“类型信息不足”问题外,还有“这是Expression 还是代表?”在将 lambda 转换为可以存储在变量中的东西时必须解决的问题。 【参考方案1】:

您需要使用Func 类型声明委托(这里的方法是一个函数,就像在JavaScript 中一样)才能使用lambda syntax:

Func<int, int> square = value => value * value;

正如@DmitryBychenko 在他的回答中指出的那样,我们需要指定一个类型而不是使用var,因为C# 是一种强类型的OOP 编译语言,而不是像JavaScript 那样的松散类型解释。

因此我们可以这样称呼它:

int result = square(2); 

但在最新版本的 C# 中,编译器会发出警告以使用 local method 代替:

int square(int value) => value * value;

Lambda 语法不是一种类型,而是一种语言语法:我们不能“call a lambda”,因为我们不能直接调用方法中的某一行代码,除非我们调用方法本身。 p>

委托和 Func/Action 以及实例和本地方法都是类型:因此我们调用方法

例如本地方法以及 Func 委托 lambda 样式与以下内容完全相同:

int square(int value)

  return value * value;

本地委托或 func/action 样式 (anonymous methods) 与本地方法之间存在一些差异。

Difference between sending an anonymous function vs. Func/Action to another function with a Delegate parameter?

Local function vs Lambda C# 7.0

Dissecting the local functions in C# 7

【讨论】:

【参考方案2】:

问题

 var square = (x) => x * x;

是编译器无法从正确的值推断square类型。可以

 Func<int, int> square = (x) => x * x;
 Func<int, double> square = (x) => x * x;
 Func<double, double> square = (x) => x * x;
 ...
 // if some MyType implements * operator
 Func<MyType, MyType> square = (x) => x * x;

这就是为什么您必须手动提供所需的类型,例如

 // We square integer (not double, not decimal) values:
 // we take int and return int 
 Func<int, int> square = (x) => x * x;

【讨论】:

Expression&lt;Func&lt;int,int&gt;&gt;

以上是关于调用 lambda 表达式而不将其分配给委托的主要内容,如果未能解决你的问题,请参考以下文章

访问非静态类的属性而不将其分配给变量

委托关键字与 lambda 表示法

C# 委托 线程

如何逐行读取大型文本文件,而不将其加载到内存中?

设置自定义异常的消息而不将其传递给基本构造函数

C# 委托 —— 委托 泛型委托与Lambda表达式