2

通过简单介绍一本书(领先一本书),有一件事引起了我的注意——lambda表达式定义:

lambda 表达式是代替委托实例编写的未命名方法。

代替委托实例???

委托实例是引用/封装目标方法的对象:

在以下示例中,右侧(lambda 表达式所在的位置)不是委托实例。这是一种方法。

TransformerDelegate t = SquareMethod;

所以定义应该已经更正/提及:

lambda 表达式是代替委托变量引用的方法(!)编写的未命名方法。

TransformerDelegate sqr = x => x * x;
                              ^
                              |
               ---------------+
               |

            this is the location for method/anonymous methods.

你明白我的意思吗?我对吗?

ps我确实理解了msdn的:(但想看看这本书是否犯了错误)

lambda 表达式是一个匿名函数,可以包含表达式和语句,并可用于创建委托或表达式树类型。

4

3 回答 3

4

lambda 表达式的值一个委托实例。

所以这本书可能指的是这样的代码:

MySquareDelegate f1 = x => x * x;
MySquareDelegate f2 = new MySquareDelegate(MySquareMethod);
MySquareDelegate f3 = MySquareMethod;  // just shorthand for the previous line

用 1 句话解释很棘手,你自己的版本

lambda 表达式是代替委托变量引用的方法(!)编写的未命名方法。

正在谈论“方法而不是方法”,原来是关于“方法而不是委托实例”,其中方法被隐式转换为委托实例。至少两者似乎都不完整。

lambda 的定义还应该包括它是一个内联方法。

于 2012-12-20T12:58:08.547 回答
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;

最后,语句 lambda 不能转换为表达式树:

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 表达式来创建表达式树而不是委托实例。

于 2012-12-20T20:13:44.010 回答
0

基本上,委托只不过是一个知道如何调用特定方法的对象。因此,委托实例实际上充当调用者的委托:调用者调用委托,然后委托调用目标方法。

于 2012-12-20T13:00:16.517 回答