C# - 匿名委托

17

我使用 "delegate" 关键字声明的委托跟匿名方法一样,是匿名委托吗?

namespace Test
{
    public delegate void MyDelegate();
    class Program
    {
        static void Main(string[] args)
        {
            DelegateTest tst = new DelegateTest();
            tst.Chaining();
            Console.ReadKey(true);
        }
    }

    class DelegateTest
    {
        public event MyDelegate del;

        public void Chaining()
        {
            del += delegate { Console.WriteLine("Hello World"); };
            del += delegate { Console.WriteLine("Good Things"); };
            del += delegate { Console.WriteLine("Wonderful World"); };
            del();
        }
    }
}
7个回答

25

“匿名委托”这个术语并不存在(或者说在C#规范和我所知道的任何其他.NET相关规范中都没有被认可)。

存在着匿名函数,其中包含匿名方法和lambda表达式。

您的代码展示了普通的匿名方法——虽然它们正在使用lambda表达式没有的一个特性:当您不关心它们时,能够完全不表达参数。


1
@Shekhar_Pro:“匿名方法”是正确的。 “匿名委托”是不正确的。你说你“通常在任何地方都能看到[它]”-你能引用具体的地方吗? - Jon Skeet
2
@Shekhar_Pro:是的,有很多术语被错误地使用了 :( - Jon Skeet
谢谢。我猜匿名方法被称为“匿名委托”,是因为在它们的定义中使用了“delegate”。当我看到匿名方法的定义时,由于出现了“delegate”,我曾将其误认为是委托类型的定义。在匿名方法的定义和委托类型的定义中使用的“delegate”是否相同?《C#入门经典》指出,在前一种情况下使用的“delegate”是一个关键字,那么在后一种情况下使用的“delegate”也是同样的关键字吗? - Tim
@Tim:它们都指的是同一个概念,是的 - 匿名方法总是转换为委托类型。 - Jon Skeet
“匿名方法始终会转换为委托类型”,这句话的意思是C#编译器总是将匿名方法转换为委托类型的实例吗? - Tim
显示剩余10条评论

20

1
链接已失效,但可能指向类似于此链接的内容:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/delegates-with-named-vs-anonymous-methods - Michael Santos

4

没错,你已经给一个事件分配了若干个匿名方法。

如果你正在使用较新版本的C#,你也可以使用lambda表达式来实现类似的功能。例如:

class DelegateTest
{
    public event Action del;

    public void Chaining()
    {
        del += () => Console.WriteLine("Hello World");
        del += () => Console.WriteLine("Good Things");
        del += () => Console.WriteLine("Wonderful World");
        del();
    }
}

2
是的,它们是匿名委托(更具体地说,是调用匿名方法的委托)。

2
是的。匿名委托无法直接使用名称引用,因此使用 delegate(){} 语法表示它们是匿名的。

2
您的委托不是匿名的,它被称为MyDelegate。在CLR中,委托是从System.MulticastDelegate派生的类,在您的情况下它被称为MyDelegate。您不能直接从MulticastDelegate派生,C#编译器会阻止您这样做。
在您的代码中,当您将委托分配给del时,编译器根据您声明的del作为类型为MyDelegate的事件来推断委托的类型/名称。

1

它们是匿名方法的委托。这是自 .NET 2.0 起可用的一种创建匿名方法的方式。使用 .NET 3.0,您也可以使用更简单的 Lambda 表达式来编写代码(但编译成相同的代码)。我想这就是您说的“匿名方法”吧。但实际上,它们是同一件事。


Lambda表达式和lambda语法中的匿名方法并不完全相同。如果您使用带有花括号的lambda语法,那么您的陈述是正确的:(x) => {y();} - Lucero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接