是否有一名代表不是';C#中的多播委托?

是否有一名代表不是';C#中的多播委托?,c#,.net,delegates,multicastdelegate,C#,.net,Delegates,Multicastdelegate,我想答案是否定的?如果没有,为什么要将Delegate和multicast Delegate类分开?可能又是因为“其他一些.NET语言”?不,CLR不允许这样做 我回忆起一些他们想直接公开的Delegate,但这从来都不需要。不,没有,因为所有的委托都必须能够自然地成为Delegate。合并ed。Delegate只是为了将非多播功能包装到基类中。编辑:我以为这是ECMA 335的一部分,但我在那里什么地方都看不到 不能在C#中创建这样的委托类型,但可以在IL中: .class public au

我想答案是否定的?如果没有,为什么要将
Delegate
multicast Delegate
类分开?可能又是因为“其他一些.NET语言”?

不,CLR不允许这样做


我回忆起一些他们想直接公开的
Delegate
,但这从来都不需要。

不,没有,因为所有的委托都必须能够自然地成为
Delegate。合并
ed。Delegate只是为了将非多播功能包装到基类中。

编辑:我以为这是ECMA 335的一部分,但我在那里什么地方都看不到

不能在C#中创建这样的委托类型,但可以在IL中:

.class public auto ansi sealed Foo
       extends [mscorlib]System.Delegate
{
    // Body as normal
}
C#编译器使用这样的委托没有问题:

using System;

class Test
{
    static void Main()
    {
        Foo f = x => Console.WriteLine(x);
        f("hello");
    }
}
但CLR在尝试加载时会执行以下操作:

未处理的异常:System.TypeLoadException:无法从程序集“Foo,Version=0.0.0,Culture=neutral,PublicKeyToken=null”加载类型“Foo”,因为它无法直接从委托类继承。 在Test.Main()中

基本上,代理/多播代理分离是一个历史性的意外。我相信早期的alpha/beta版本确实做出了区分,但它被证明太混乱,通常没有用处——因此现在每个委托都来自多播委托


(有趣的是,在不能用作一般约束的类型列表中,C#规范只提到MulticastDelegate一次。)

System.MulticastDelegate是从System.Delegate派生而来的。 委托层次结构中的每个级别都提供一组不同的服务。委托是一个数据容器,用于在特定对象上调用什么方法。通过System.MulticastDelegate,不仅可以在单个对象上调用方法,还可以在对象集合上调用方法。这将允许多个订阅服务器订阅一个事件


不确定,我已经回答了你的问题。

虽然听起来很合适,但它没有解释为什么GetInvocationList(显然是关于调用多个方法)是委托的一部分,而不是MulticastDelegate…PEVerify对使用
Foo
的程序集说了什么?@leppie:还没有尝试过。请随意这样做:)(我只是在一个“正常”声明上运行ildasm来获取IL,然后对其进行修改并重新ilasmed。)我将ilasm/ildasm用于测试代理,并在您的答案中获得了预期结果。谢谢。CLR有什么理由强制执行此约束吗?有好几次我希望一个事件只能有一个订阅者。这可以通过指定您自己的
add
/
remove
来实现,但使用非多播委托会使这更简单。@JonathonReinhart:不知道,恐怕:(即使每个委托都有一个方法指针和目标,delegate.Combine也可以很好地实现:只需创建一个具有两个适当委托类型的字段的对象,并按顺序运行它们。在运行具有大量子委托的委托的情况下,使用多播委托可以提供性能优势。)通常,但很少涉及合并和删除,但如果它在更典型的情况下产生更好的性能,我会感到惊讶。就个人而言,我希望有一个可变的“事件列表”类型,可能是一个结构,其中有一个Object类型的字段……可以包含null、一个委托或一个委托数组,其中包括一个方法,可以根据需要调用该字段并执行线程安全的添加和删除操作(使用Interlocked.CompareExchange);调用方法应该提供在第一个异常时停止的选择,或者让所有处理程序运行并抛出一个BundledException以及运行它们时发生的所有异常的列表。让事件列表保留委托引用,而不是方法和目标的列表,将消除现有方法中的怪癖。