2011-10-01 12 views
2

私はそれが動作すると予想されるように動作しない単純なプログラムを持っています。それが判明れるようC#デリゲート/イベント処理について

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

:私は、両方のメソッドシグネチャがCallEvent()メソッドの間の委任の呼び出しリストの順に実行し、作るテストプロパティをそこで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つの戻り値[1]しか存在できませんが、実際に最後に呼び出された代理人の両方がその値を返しました。

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

コール・フー回または複数回:どのようなフレームワークは、あなたが直接引数としてメソッドで、あなたのイベントを置く場合に何をすべきか知っている必要があるのでこれは、理にかなっていますか?どういうわけか値を組み合わせる?あなたはそれがはっきりしないのを見る。

デリゲートの順番も定義されていないことを追加する必要があります。[2]、よく定義されていますが(登録の順番)、決してそれに頼るべきではありません。

+0

これは私が探していたものです。 :) –

3

+ =演算子を使用すると、新しいデリゲートを呼び出しチェーンに追加します。チェーンは評価方法です。各デリゲートはチェーン内で順番に呼び出されます。しかし、デリゲートがすべて呼び出される(呼び出し元をブロックして値を返すことを意味する)ので、最後の結果だけが代入に返されます。

この例は単純化したもので、デリゲートに結果を持たせるのではなく、ラムダ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

関連する問題