2011-10-01 157 views
2

我有一個簡單的程序,其行爲不像我預期的那樣行爲。我的印象是,這兩個方法簽名會在委託的調用列表的順序CallEvent()方法的過程中運行,使測試屬性等同於40.因此:關於C#委託/事件處理

Test += (20+15); 
Test += (20-15); 
Test == 40; 

,因爲它會變成,這個賦值等於5,這是減法的值。如果它先做了加法,然後用減法代替它,是不是沒有達到Test + =賦值的目的?也許它正在繞過所有的一起(但不太可能)。我懷疑更多內在的東西正在發生,我無法看到我目前的編程知識。

請和謝謝你! LiquidWotter

//MY NAMESPACE 
namespace MyNamespace 
{ 
    //MAIN 
    private static void Main(string[] args) 
    { 
     //CREATE MY OBJECT 
     MyClass MyObject = new MyClass(); 

     //ADD CALLS TO EVENT 
     MyObject.MyEvent += Add; 
     MyObject.MyEvent += Sub; 

     //CALL EVENT AND WRITE 
     MyObject.CallEvent(20, 15); 
     Console.WriteLine(MyObject.Test.ToString()); 

     //PAUSE 
     Console.ReadLine(); 
    } 

    //ADDITION 
    private static int Add(int x, int y) 
    { return x + y; } 

    //SUBTRACTION 
    private static int Sub(int x, int y) 
    { return x - y; } 

    //MY CLASS 
    public class MyClass 
    { 
     //MEMBERS 
     public delegate int MyDelegate(int x, int y); 
     public event MyDelegate MyEvent; 
     public int Test { get; set; } 

     //CONSTRUCTOR 
     public MyClass() 
     { 
      this.Test = 0; 
     } 

     //CALL Event 
     public void CallEvent(int x, int y) 
     { 
      Test += MyEvent(x, y); 
     } 
    } 
} 
+1

你並不是真正按照他們的意圖使用事件。如果你想存儲一個委託,把它存儲在一個變量中。這不是一個事件的作用。 –

+0

你偶然發現所有事件都應該是'void f(...)' –

回答

3

那麼你是正確的。只能有一個返回值[1],而只調用一個的實際上是最後一個的代表返回了它的值。這是有道理的,因爲該框架應如何知道在情況下,你直接把你的事件的方法作爲參數做:

this.Foo(MyEvent(x, y)); 

調用foo一次或多次?以某種方式結合了價值觀?你看它不清楚。

我必須補充說,代表的順序也沒有定義[2],目前它已被定義(註冊順序),但你不應該依賴它。

+0

這就是我正在尋找的,謝謝你的參考。 :) –

3

使用+ =操作符將新代理添加到調用鏈。鏈是如何評估的。每個代表將在鏈中按順序調用。但是,因爲代表都被調用(意味着它們阻止並向調用方返回一個值),所以只有最後一個結果返回到您的任務中。

假設這個例子是一個簡化,而不是委託人的結果,你可以使用lambda epxressions和Linq擴展集合Sum或簡單地維護你的類的狀態。

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    //MAIN 
    private static void Main(string[] args) 
    { 
     IEnumerable<Func<int, int, int>> operationsList = 
      new Func<int,int, int>[] { Add, Sub }; 

     //CALL EVENTs AND WRITE 
     Console.WriteLine(operationsList.Sum(operation => operation(20, 15))); 

     //PAUSE 
     Console.ReadLine(); 
    } 

    //ADDITION 
    private static int Add(int x, int y) 
    { 
     return x + y; 
    } 

    //SUBTRACTION 
    private static int Sub(int x, int y) 
    { 
     return x - y; 
    } 
} 
+0

這是真正解決程序問題的好方法!但是,我的問題是關於代表和事件的性質。我很困惑他們爲什麼沒有按我預期的方式工作。 :) –

+0

+1爲了給出一個替代方案,這是我的文章中缺少的東西。 – dowhilefor