2012-05-12 31 views
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(); } 
} 

可以在第二示例代碼進行修改,以使代表運行添加方法,而不是乘法方法?

回答

2

當您的委託具有多個附加到它的函數時,將依次調用每個函數。如果委託具有非空的返回值,則返回最後一個函數的返回值。

language specification,15.4委託調用,說

如果委託調用包含輸出參數或一個返回值,最終值將來自該列表中的最後一個委託的調用。

所以,當你調用foo.Invoke(10, 20),會發生以下情況:

  • 首先,add(10, 20)被稱爲返回30
  • 然後,multiply(10, 20)被稱爲返回200和值返回到原來的來電者。

在你的跟進問題,你問

可以在第二示例代碼進行修改,以使 委託運行添加方法,而不是乘 方法?

如上所述,均執行add方法multiply方法。從上次執行的方法返回的值是返回給調用者的。因此,如果您想要返回調用add產生的值,它必須是添加到委託實例的最後一個方法。

+0

我該如何修改它,使其運行添加而不是繁殖? – whytheq

+0

它總是會同時執行。您可以將一個函數添加到委託實例中。或者你可以最後添加add函數。你已經清楚地知道委託調用如何處理返回值。你沒有告訴的是你的最終目標是什麼。你想解決什麼問題? –

+0

我只是想了解代表!無非是好奇心大衛。如果兩個函數都添加到委託中,如果我無法得到它,添加第一個函數有什麼意義? – whytheq

2

C# language specification(§22.3):

委託實例的

調用其調用列表包含多個條目,前進通過調用的方法的每一箇中 調用列表,同步地,爲了。所調用的每個方法都將傳遞給與委託實例相同的參數集 。如果這樣的委託調用包含參考 參數(第17.5.1.2節),則每個方法調用都會引用相同的變量;更改爲 調用列表中的一個方法的變量對調用列表下方的方法可見。 如果委託調用包含輸出參數或返回值,則它們的最終值將來自調用列表中最後一個委託的 。如果在處理調用這樣的代理時發生異常,並且該異常未在被調用的方法中捕獲,那麼在調用委託的方法中繼續搜索異常 ,並進一步執行任何方法向下調用 列表不會被調用。

+0

我如何修改它,使其運行添加而不是相乘? – whytheq

相關問題