使用多播代理链接功能

why*_*heq 10 c# delegates

我的问题在下面的代码中有详细说明 - 我之所以问这个原因是我正在试验代表:

//create the delegate          
delegate int del(int x);

class Program {


    static void Main(string[] args) {

        Program p;
        p = new Program();

        del d = p.a;
        d += p.b;
        d += p.c;
        d += p.d;
        d += p.e;
        Console.WriteLine(d(10)); //<<was hoping it would be 10+2+3+4+5+6

        Console.WriteLine("press [enter] to exit");
        Console.ReadLine();
    }

    private int a(int x) { Console.WriteLine("a is called"); return x + 2; }
    private int b(int x) { Console.WriteLine("b is called"); return x + 3; }
    private int c(int x) { Console.WriteLine("c is called"); return x + 4; }
    private int d(int x) { Console.WriteLine("d is called"); return x + 5; }
    private int e(int x) { Console.WriteLine("e is called"); return x + 6; }

} 
Run Code Online (Sandbox Code Playgroud)

16被退回....

在此输入图像描述

所有的函数都会触发,因为各种消息"a被调用"等都被打印到了,console但只返回了从最后一个函数e返回的数量 - 我假设在后台他们正在返回但是然后被覆盖了?

Jep*_*sen 14

如果您有问题中的多播委托d,则返回值是调用列表的最后一个方法的返回值d.

通常,对于多播委托,使用返回类型是最自然的void.

编译器没有机会猜测你是希望的10+2+3+4+5+6.你没有在任何地方指定它.

您可以将您的委托类型更改为:

delegate void del(int xToAdd, ref int sum);
Run Code Online (Sandbox Code Playgroud)

那么你的方法a应该如下所示:

private void a(int x, ref int sum) { Console.WriteLine("a is called"); sum += x + 2; }
Run Code Online (Sandbox Code Playgroud)

d然后将像这样调用多播委托实例:

int sum = 0;
d(10, ref sum);
Console.WriteLine(sum);
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助.


Ser*_*rvy 9

这不是代表处理返回类型的方式.会发生什么是所有的处理程序将彼此独立地执行,然后将随机选择一个(技术上它是最后订阅的处理程序,但你不应该依赖它)返回给调用者调用委托.

我强烈反对你不要使用具有返回值的事件(你将这个代理看作是一个事件).这种行为几乎不可取.如果你想要一个返回值,那么确保你的委托总是映射到一个函数是合理的,不多也不少.

至于实际产生期望的结果,虽然有许多方法,但更好的服务是更传统的代表集合:

List<Func<int, int>> functions = new List<Func<int, int>>();
//populate

int result = functions.Aggregate(10, (total, func) => func(total));
Run Code Online (Sandbox Code Playgroud)

  • 调用列表中的方法按顺序调用,使用最后一个调用的返回值(它不是随机选择的),你可以**依赖它.引用C#规范:_"通过按顺序同步调用调用列表中的每个方法来调用其调用列表包含多个条目的委托实例."_此外,返回值_"将来自调用列表中的最后一个委托."_同一段也保证可以使用`ref`参数,就像我在答案中所做的那样. (2认同)