【问题标题】:Multicast Delegates must have a return type of void. Why?多播委托的返回类型必须为 void。为什么?
【发布时间】:2012-09-13 21:22:00
【问题描述】:

Multicast Delegates 的返回类型必须为 void,否则会抛出异常。

我想知道它背后的原因是什么,如果多个方法可以具有与委托相同的返回类型怎么办?

【问题讨论】:

  • 你能提供一个抛出异常的例子吗?

标签: c# delegates multicastdelegate


【解决方案1】:

以下答案实际上是错误的,因为您目前*可以*拥有具有非 void 返回类型的多播委托(关于这是否一直如此,尚无定论)。但是,它确实回答了“为什么一种语言不允许这样的代表?”这个问题,所以为了完整起见,我将其保留。

现在去投票给 Marc。


因为多个方法会返回多个值,那么委托的一个返回值应该是什么呢?显然,没有任何答案可以在所有情况下都令人满意。您可以争辩说多播委托应该:

  • 按调用顺序返回第一个方法的值(但未指定 IIRC 调用顺序,那么这将如何工作?)
  • 返回最后一个方法的值,如上
  • 返回所有委托返回的单个不同值;如果不是所有人都同意,则抛出异常

【讨论】:

  • 需要注意的是,.NET 中的所有委托都是多播委托。
  • @DanielHilgarth:你指的是类名和它支持的功能吗?如果是这样,那么从技术上讲,您是正确的,但是“所有代表都是多播”会留下错误的印象。显然,您可以拥有具有非 void 返回类型的委托,这需要与您的声明相协调。
  • 查看 Marc 的回答。这正是我的意思。
  • 参见Jon Skeet's article:“Delegate 和 MulticastDelegate 之间的区别在很大程度上是历史性的;在 .NET 1.0 的测试版中,这种区别是显着的(并且令人讨厌)——微软考虑将这两种类型合并在一起,但最终决定了在发布周期中为时已晚,无法进行如此重大的更改。您几乎可以假装它们只是一种类型。”
  • @MarcGravell:谢谢,我知道代表来自MulticastDelegate,正如丹尼尔和您的原始评论所揭示的那样。但是,我错误地认为MulticastDelegate 不会让你组合,除非返回类型是void
【解决方案2】:

在多播中的问题是它会覆盖所有值,如果它具有返回类型,则只打印最后一个方法值,因此您必须逐个捕获返回类型,让我们看下面的代码

 class Program
{
    // i am going to add and subtract two num but i wanna get result in string the same thing you can do for int and what ever you want
      delegate string mydeledagte(int a,int b);
      delegate string d(int s, int t);
    static void Main(string[] args)
    {
        mydeledagte ab = new mydeledagte(ad);
        mydeledagte d= new mydeledagte(sub);
        mydeledagte multi = ab + d;

        foreach (mydeledagte individualMI in multi.GetInvocationList())
        {
            string retVal = individualMI(3, 5);
            Console.WriteLine("Output: " + retVal);
            Console.WriteLine("\n***developer of KUST***");
            Console.ReadKey();
        }
    }
    static string ad(int a, int b)
    {

        return (a + b).ToString();

    }
    static string sub(int a, int b)
    {

        return (a - b).ToString(); ;
    }
}

【讨论】:

    【解决方案3】:

    前提是错误的;它工作正常:

    Func<int> func = delegate { Console.WriteLine("first part"); return 5; };
    func += delegate { Console.WriteLine("second part"); return 7; };
    int result = func();
    

    这是一个非空结果的多播委托,工作正常。您可以从控制台看到这两个部分都已执行。 last 项的结果是返回的那个。我们可以证明这是一个真正的多播委托:

    if(func is MulticastDelegate) Console.WriteLine("I'm multicast");
    

    它会写“我在多播”即使在第一行之后(当只列出一个方法时)。

    如果您需要对单个结果进行更多控制,请使用GetInvocationList()

    foreach (Func<int> part in func.GetInvocationList())
    {
        int result = part();
    }
    

    它允许您查看每个单独的结果。

    在 IL 术语中:

    .class public auto ansi sealed Func<+ TResult>
        extends System.MulticastDelegate`
    

    也就是说:Func&lt;T&gt; 继承自 MulticastDelegate。基本上,就所有意图和目的而言,.NET 中的所有委托都是多播委托。您可能能够在托管 C++ 中获得非多播委托,我不知道。但肯定不是来自 C#。

    【讨论】:

    • @Jon 来自记忆,这可能是 .NET 1.0 和 .NET 1.1 之间的重大变化之一
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2012-04-11
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多