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

时间:2012-05-12 21:22:17

标签: c# delegates

在按钮1上单击一个又一个消息框出现 - 首先显示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方法而不是乘法方法?

2 个答案:

答案 0 :(得分:2)

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

language specification,15.4委托调用,

  

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

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

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

在你的后续问题中,你问

  

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

如上所述,add方法 multiply方法都已执行。 上次执行方法的返回值是返回给调用者的返回值。因此,如果您希望返回调用add得到的值,则它必须是添加到委托实例的最后一个方法。

答案 1 :(得分:2)

来自C# language specification(§22.3):

  

调用其调用列表包含多个条目的委托实例,通过调用每个条目来继续   调度列表中的方法,按顺序同步。所谓的每个方法都传递给同一个集合   赋予委托实例的参数。如果这样的委托调用包括引用   参数(§17.5.1.2),每个方法调用都会发生与同一个变量的引用;改变为   调用列表中的一个方法的变量对于调用列表中的下一个方法是可见的。   如果委托调用包含输出参数或返回值,则它们的最终值将来自   调用列表中的最后一个委托。如果在处理这样的a的调用期间发生异常   委托,并且该异常不会在调用的方法中捕获,即搜索异常   catch子句继续在调用委托的方法中,以及调用之后的任何方法   列表未被调用。