2012-05-12 2 views
1

На button1_Click один MessageBox за другим появляются - первый показ 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(); } 
} 

Может второй образец кода быть изменен таким образом, что делегат работает метод добавления, а не метод умножения?

ответ

2

Когда ваш делегат имеет несколько функций, связанных с ним, каждый из них вызывается по очереди. Если у делегата есть возвращаемое значение не-void, возвращаемое значение последней функции - это то, что возвращается.

language specification, 15,4 Делегат вызов, говорит

Если делегат вызов включает выходные параметры или возвращаемое значение, их окончательное значение будет исходить от вызова последнего делегата в списке.

Так что, когда вы звоните foo.Invoke(10, 20), происходит следующее:

  • Во-первых, add(10, 20) называется возвращающий 30.
  • Затем multiply(10, 20) называется, которая возвращает 200, и это значение возвращается к оригинальный вызывающий.

В вашей последующей вопрос вы спросите

Может второй образец кода быть изменен таким образом, что делегат работает метод добавления вместо умножения метода?

Как объяснено выше, метод add метод иmultiply оба выполнены. Возвращаемое значение из последнего выполненного метода - это то, что возвращается вызывающему. Итак, если вы хотите, чтобы возвращаемое значение вызывало add, это должен быть последний метод, добавленный в экземпляр делегата.

+0

Как мне изменить его так, чтобы он работал, а не умножался? – whytheq

+0

он всегда будет исполнять оба. Вы можете просто добавить одну функцию к экземпляру делегата. Или вы можете добавить функцию добавления последним. Ответы, которые у вас есть, очень четко показывают, как вызов делегата обрабатывает возвращаемые значения. То, что вы не сказали, является конечной целью. Какую проблему ты пытаешься решить? –

+0

Я просто пытаюсь понять делегатов! не более, чем любопытство Давида. Если обе функции добавляются к делегату, то в чем смысл добавления первой функции, если я не могу это понять ?! – whytheq

2

Из C# language specification (§22.3):

Инвокация экземпляра делегата, чей вызов список содержит несколько записей, доходы от обращения к каждому из методов в списке вызова, синхронно, в порядке. Каждому так называемому методу передается тот же набор аргументов, который был предоставлен экземпляру делегата. Если такой вызов делегата включает в себя параметры ссылки (§17.5.1.2), каждый вызов метода будет происходить со ссылкой на ту же переменную; изменяется на , что переменная одним методом в списке вызовов будет видна методам, расположенным далее в списке вызовов. Если вызов делегата включает выходные параметры или возвращаемое значение, их окончательное значение будет получено из вызова последнего делегата в списке. Если во время обработки вызова такого делегата возникает исключение, и это исключение не попадает в метод, который был вызван, поиск исключений продолжается в методе, который называется делегатом, и любые другие методы вниз по вызову список не вызывается.

+0

как я могу изменить его так, чтобы он работал, а не умножался? – whytheq

Смежные вопросы