1

在 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 方法而不是 multiply 方法?

4

2 回答 2

2

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

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

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

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

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

在您提出的后续问题中

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

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

于 2012-05-12T21:34:22.997 回答
2

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

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

于 2012-05-12T21:38:59.263 回答