通过简单介绍一本书(领先一本),有一件事引起了我的注意 - lambda表达式定义:
lambda表达式是一个用来代替a的未命名方法 委托实例。
代替委托实例???
委托实例是对象,它引用/封装目标方法:
在以下示例中右侧(lambda表达式所在的位置)不是委托实例。这是一种方法。
TransformerDelegate t = SquareMethod;
所以定义应该更正/提及:
lambda表达式是用来代替方法编写的未命名方法(!) 由委托变量引用。
TransformerDelegate sqr = x => x * x;
^
|
---------------+
|
this is the location for method/anonymous methods.
你知道我的意思吗?我是对的吗?
P.S。我 了解msdn的一个:(但想知道这本书是否犯了错误)
lambda表达式是一个可以包含的匿名函数 表达式和语句,可用于创建委托或 表达式树类型。
答案 0 :(得分:4)
lambda表达式的值是委托实例。
所以这本书可能指的是代码:
MySquareDelegate f1 = x => x * x;
MySquareDelegate f2 = new MySquareDelegate(MySquareMethod);
MySquareDelegate f3 = MySquareMethod; // just shorthand for the previous line
用1句话解释你自己的版本
是一件很棘手的事情lambda表达式是代替由委托变量引用的方法(!)而编写的未命名方法。
正在讨论“方法而不是方法”,原文关于“方法而不是委托实例”,其中方法被隐式转换为委托实例。两者似乎至少都不完整。
lambda的定义还应包括它是内联方法。
答案 1 :(得分:1)
其他答案错过了lambda表达式不一定代表方法的事实。有时,它们代表表达树。
编译器隐式地将lambda表达式转换为一种对象或另一种对象,具体取决于上下文。
要指定方法,您需要指定参数和正文。在lambda表达式中,它们由=>
分隔。例子:
() => 4; //empty parameter list
x => x.ToString(); //one parameter
(a, b) => a.Equals(b); //two parameters
// ^^^^^^ ^^^^^^^^^^^^
// | |
// parameter list body
这些lambda表达式可以分别转换为Func<int>
,Func<object, string>
和Func<object, object, bool>
。也可以分别转换为Expression<Func<int>>
,Expression<Func<object, string>>
和Expression<Func<object, object, bool>>
。
匿名方法:
delegate (object p, object q) { return string.Concat(p, q); }
// ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// parameter list body
以下是lambda转换的两个例子:
Func<object, object, bool> aDelegate = (o1, o2) => object.Equals(o1, o2);
Expression<Func<object, object, bool>> anExpressionTree = (o1, o2) => object.Equals(o1, o2);
在方法组转换中,参数和方法体由重载决策指定。为简化一点,编译器会查看具有指定名称的方法,并根据上下文选择正确的重载。例如,考虑SquareMethod的这些重载:
int SquareMethod(int a) { return a * a; }
double SquareMethod(double a) { return a * a; }
这些语句涉及方法组转换和重载解析:
Func<int, int> squareAnInt = SquareMethod;
Func<double, double> squareADouble = SquareMethod;
最后,语句lambdas无法转换为表达式树:
Action<object> anAction = o => { Console.WriteLine(o); };
Func<object, int> aFunc = o =>
{
var s = (o ?? "").ToString();
Console.WriteLine(s);
return s.Length;
};
C#语言规范(有点令人困惑)使用术语“匿名函数”来涵盖lambda表达式和匿名方法。匿名函数可以隐式转换为兼容的委托类型,方法组也可以。因此,如果我们有一个名为DelegateType
的委托类型,并且声明/赋值如下:
DelegateType d = [something];
然后[something]
可以是方法组或匿名函数。换句话说,它可以是方法组,匿名方法或lambda表达式。
所以,你对书中文本的修正会更好地说“代替一个方法组”,但我会说
lambda表达式是一个未命名的方法,与命名方法组一样,可用于创建委托实例。
我可能还会添加
在某些情况下,lambda表达式可用于创建表达式树而不是委托实例。
答案 2 :(得分:0)
基本上,委托只不过是一个知道如何调用特定方法的对象。因此委托实例字面上充当调用者的委托:调用者调用委托,然后委托调用目标方法。