简体   繁体   English

关于以防万一,C#匿名方法的语法比lambda表达式的语法简单。 书:Professional C#5.0和.NET 4.5.1

[英]About in case,C# the syntax of anonymous methods simpler than syntax of lambda expressions. Book:Professional C# 5.0 and .NET 4.5.1

Recently, i read "Professional C# 5.0 and .NET 4.5.1 by Christian Nagel; Jay Glynn; Morgan Skinner" book. 最近,我读了“Christian Cage的专业C#5.0和.NET 4.5.1; Jay Glynn; Morgan Skinner”一书。 And i confused about: "in case,the syntax of anonymous methods simpler than syntax of lambda expressions" in book. 我对此感到困惑:“以防万一,匿名方法的语法比lambda表达式的语法更简单”。

Details in Chapter 8: Delegates, Lambdas, and Events 第8章中的详细信息:Delegates,Lambdas和Events

LAMBDA EXPRESSIONS "NOTE The syntax of lambda expressions is simpler than the syntax of anonymous methods. In a case where a method to be invoked has parameters and you don't need the parameters, the syntax of anonymous methods is simpler, as you don't need to supply parameters in that case ." LAMBDA EXPRESSIONS“注意lambda表达式的语法比匿名方法的语法简单。在要调用的方法有参数但不需要参数的情况下,匿名方法的语法更简单,因为你不能在这种情况下需要提供参数 。“

Can anyone explain/sample why anonymous methods don't need to supply parameters in that case? 任何人都可以解释/示例为什么匿名方法在这种情况下不需要提供参数?

Because this is valid 因为这是有效的

Func<int,int> f = delegate { return 47; }

But this is not 但事实并非如此

Func<int,int> f = () =>  47;

With anonymous method syntax you can omit the parameters if you don't need them. 使用匿名方法语法,如果不需要,可以省略参数。 But in lambda expression you have to supply parameters. 但是在lambda表达式中,你必须提供参数。

This has been also stated in the documentation : 文档中也说明了这一点:

There is one case in which an anonymous method provides functionality not found in lambda expressions. 有一种情况是匿名方法提供lambda表达式中没有的功能。 Anonymous methods enable you to omit the parameter list.This means that an anonymous method can be converted to delegates with a variety of signatures. 匿名方法使您可以省略参数列表。这意味着可以将匿名方法转换为具有各种签名的委托。

Can anyone explain/sample why anonymous methods don't need to supply parameters in that case? 任何人都可以解释/示例为什么匿名方法在这种情况下不需要提供参数?

Because if you're not using the delegate parameters, you can leave it up to the compiler to auto-generate them for you. 因为如果您没有使用委托参数,则可以将其留给编译器为您自动生成它们。

Example: 例:

internal delegate void MyDelegate(string s);

public class Foo
{
    public void F()
    {
        MyDelegate del = delegate { Console.WriteLine("hello!"); };
    }
}

When i specify no parameters (because im not explicitly using them in my delegate), the compiler translates it into the following: 当我没有指定参数时(因为我没有在我的委托中明确使用它们),编译器会将其转换为以下内容:

public void F()
{
    MyDelegate del = delegate(string param0)
    {
        Console.WriteLine("hello!");
    };
}

Or if you want the real nasty stuff: 或者如果你想要真正讨厌的东西:

[CompilerGenerated]
private static void <F>b__0(string param0)
{
    Console.WriteLine("hello!");
}

public void F()
{
    if (Foo.CS$<>9__CachedAnonymousMethodDelegate1 == null)
    {
        Foo.CS$<>9__CachedAnonymousMethodDelegate1 = new MyDelegate(Foo.<F>b__0);
    }
    MyDelegate del = Foo.CS$<>9__CachedAnonymousMethodDelegate1;
}

If your method expected a parameter you need to define/use it eitherway be it lambda expressions or anonymous methods. 如果你的方法需要一个参数,你需要定义/使用它,无论是lambda表达式还是匿名方法。
Lets say you have a delegate declared like below. 假设您有一个如下所述的委托。

public delegate void PrintDelegate(string message);

you can assign either lambda expression or anonymous method to it like below 您可以像下面一样为其分配lambda表达式或匿名方法

Lambda Expression Lambda表达

PrintDelegate p1 = message => { Console.WriteLine(message); };

Anonymous Expression 匿名表达

PrintDelegate p2 = delegate(string text) { Console.WriteLine(text); };

In both these you see that the parameter has be defined. 在这两个中,您都会看到已定义参数。
However if you want to hook the delegate to another method with the same signature you can do like below. 但是,如果要将委托挂钩到具有相同签名的另一个方法,则可以执行以下操作。

PrintDelegate p1 = Console.WriteLine;

Console.WriteLine has the same signature as the defined delegate so you need not specify the parameter explicitly when defining the delegate. Console.WriteLine与定义的委托具有相同的签名,因此在定义委托时无需显式指定参数。

All these variations can be invoked normally and will give the same output. 所有这些变化都可以正常调用,并提供相同的输出。

p1("Hello World");

Note other answers where the parameters is not used in defining the anonymous method you cannot use the passed value of the parameter inside the anonymous method which is not the ideal way to declare a delegate body. 注意其他答案,其中参数未用于定义匿名方法,您不能使用匿名方法中参数的传递值,这不是声明委托主体的理想方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM