为什么程序使用添加到委托的最后一个方法

本文关键字:最后一个 方法 程序 添加 为什么 | 更新日期: 2023-09-27 18:33:55

button1_click出现一个又一个的消息框 - 第一个显示 30,第二个显示 200:

public partial class Form1 : Form
{
    delegate void myMathFunction(int j, int q);
    void add(int x, int y) {MessageBox.Show((x + y).ToString());}
    void multiply(int x, int y){MessageBox.Show((x*y).ToString());}
    private void button1_Click(object sender, EventArgs e)
    {
        myMathFunction foo = new myMathFunction(add);
        foo+= new myMathFunction(multiply);
        foo.Invoke(10, 20);
    }
    public Form1() { InitializeComponent(); }
}

但以下内容直接进入 200,但我已将两种方法都分配给委托 - 添加发生了什么,为什么它选择使用乘法?

public partial class Form1 : Form
{
    delegate int myMathFunction(int j, int q);
    int add(int x, int y){return x + y;}
    int multiply(int x, int y) {return x * y;}
    private void button1_Click(object sender, EventArgs e)
    {
        myMathFunction foo = new myMathFunction(add);
        foo += new myMathFunction(multiply);
        MessageBox.Show(foo.Invoke(10, 20).ToString());
    }
    public Form1() { InitializeComponent(); }
}

是否可以修改第二个代码示例,以便委托运行 add 方法而不是乘法方法?

为什么程序使用添加到委托的最后一个方法

当委托附加了多个函数时,将依次调用每个函数。如果委托具有非 void 返回值,则最后一个函数的返回值是返回的值。

语言规范,15.4 委托调用,说

如果委托调用包括输出参数或返回值,则其最终值将来自列表中最后一个委托的调用。

因此,当您调用 foo.Invoke(10, 20) 时,会发生以下情况:

  • 首先,调用返回 30 的add(10, 20)
  • 然后,调用返回 200 的 multiply(10, 20),并将该值返回给原始调用方。

在您的后续问题中,您问

是否可以修改第二个代码示例,以便 委托运行 add 方法而不是乘法 方法?

如上所述,add方法multiply方法都执行。上次执行的方法的返回值是返回给调用方的值。因此,如果要返回调用add生成的值,它必须是添加到委托实例的最后一个方法。

来自 C# 语言规范 (§22.3(:

调用其

调用列表包含多个条目的委托实例,通过调用每个条目进行 调用列表中的方法,按顺序同步。所谓的每个方法都传递相同的集合 提供给委托实例的参数。如果此类委托调用包含引用 参数 (§17.5.1.2(,每个方法调用都将引用相同的变量;更改为 调用列表中一个方法的变量将对调用列表中更靠后的方法可见。 如果委托调用包含输出参数或返回值,则其最终值将来自 调用列表中的最后一个委托。如果在处理此类调用期间发生异常 委托,并且该异常未在调用的方法中捕获,搜索异常 catch 子句在调用委托的方法中继续,以及调用中进一步向下的任何方法 不调用列表。