8

以下がある場合:

public static void main() { 
    MyClass1 obj = new MyClass1();
    obj.Method1();
}
public class MyClass1() {
    public void Method1() {
        MyClass2 obj = new MyClass2();
        obj.Method1();
    }
}
public class MyClass2() {
   public void Method1() {
       MyClass3 obj = new MyClass3();
       obj.Method1();
   }
}
public class MyClass3() {
   public void Method1() {
       // Raise event here that is handled in MyClass1?    
   }
}

MyClass3.Method1()で処理されるイベントを発生させることができますMyClass1か?

これを達成したい場合、イベント処理コードはどのように記述されますか?

4

5 に答える 5

4

はい、可能ですが、各レベルはチェーンのより深いレベルを認識していないため、各クラスでイベントを作成する必要があります。このようないくつか:

public static void main() { 
    MyClass1 obj = new MyClass1();
    obj.MyEvent += (s, e) => { Console.WriteLine("Fired!"); };
    obj.Method1();
}

public class MyClass1 {
    public void Method1() {
        MyClass2 obj = new MyClass2();
        obj.MyEvent += (s, e) => { OnMyEvent(); };
        obj.Method1();
    }
    public event EventHandler MyEvent;
    private void OnMyEvent() {
        var myEvent = MyEvent;
        if (myEvent != null)
            myEvent(this, EventArgs.Empty);
    }
}
public class MyClass2 {
    public void Method1() {
        MyClass3 obj = new MyClass3();
        obj.MyEvent += (s, e) => { OnMyEvent(); };
        obj.Method1();
    }
    public event EventHandler MyEvent;
    private void OnMyEvent() {
        var myEvent = MyEvent;
        if (myEvent != null)
            myEvent(this, EventArgs.Empty);
    }
}
public class MyClass3 {
    public void Method1() {
        // Raise event here that is handled in MyClass1?    
        OnMyEvent();
    }
    public event EventHandler MyEvent;
    private void OnMyEvent() {
        var myEvent = MyEvent;
        if (myEvent != null)
            myEvent(this, EventArgs.Empty);
    }
}
于 2012-09-03T08:07:10.467 に答える
2

イベントハンドラーをチェーンするには、MyClass2のadd/remove構文を使用します。MyClass1からSomeEventを設定し、MyClass3でそれを上げます。

public class MyClass1             
{             
    MyClass2 obj = new MyClass2(); 

    public MyClass1()
    {
        obj.SomeEvent += obj_SomeEvent;
    }

    public void Method1()             
    {                      
        obj.Method1();             
    }             

    private static void obj_SomeEvent(object sender, EventArgs e)             
    {             
        Console.WriteLine("Some event fired");             
    }             
}  


public class MyClass2() 
{    
   MyClass3 cls3 = new MyClass3();

   public void Method1() 
   {     
       cls3.FireSomeEvent();    
   }   

    public event MyEventHandler SomeEvent
    { 
        add { this.cls3.SomeEvent += value; } 
        remove { this.cls3.SomeEvent -= value; } 
    }  
}

public class MyClass3() 
{
    public event EventHandler SomeEvent;

    private void OnSomeEvent() 
    { 
        if (SomeEvent!= null) 
        { 
            SomeEvent(this, new EventArgs()); 
        } 
    } 

    public void FireSomeEvent
    {
        OnSomeEvent();
    }
}
于 2012-09-03T08:15:32.110 に答える
1

すべてのクラスでコールバック ソリューションと一連のイベントを回避したい場合は、基本的に 2 つのソリューションがあります。

最初のものは、タイプ MyClassX のローカル変数をフィールドに変換することで構成されます。つまり、Chris Gessler が提案したようなものですが、このアプローチに完全に従い、ローカル変数を削除します。

public static void main() { 
    MyClass1 obj = new MyClass1();
    obj.c2.c3.SomeEvent += obj_SomeEvent;      
    obj.Method1();
}

private static void obj_SomeEvent(object sender, EventArgs e)             
{             
    Console.WriteLine("Some event fired");             
}

public class MyClass1() {
    public MyClass2 c2 = new MyClass2();

    public void Method1() {
        c2.Method1();
    }
}
public class MyClass2() {
   public MyClass3 c3 = new MyClass3();

   public void Method1() {
       c3.Method1();
   }
}
public class MyClass3() {
    public event EventHandler SomeEvent;

    private void OnSomeEvent() 
    { 
        if (SomeEvent!= null) 
        { 
            SomeEvent(this, new EventArgs()); 
        } 
    } 
   public void Method1() {
       OnSomeEvent();    
   }
}

あなたの他のオプション(ただし、実行可能かどうかは実際に何をしようとしているかに依存しますが、とにかく好きではありません)は、単に MyClass3 のイベントを静的として定義することです:

public static void main() { 
    MyClass3.SomeEvent += obj_SomeEvent;
    MyClass1 obj = new MyClass1();
    obj.Method1();
}

private static void obj_SomeEvent(object sender, EventArgs e)             
{             
     Console.WriteLine("Some event fired");             
}

public class MyClass1() {
    public void Method1() {
        MyClass2 obj = new MyClass2();
        obj.Method1();
    }
}
public class MyClass2() {
   public void Method1() {
       MyClass3 obj = new MyClass3();
       obj.Method1();
   }
}
public class MyClass3() {
    public static event EventHandler SomeEvent;

    private void OnSomeEvent(MyClass3 anObj) 
    { 
        if (SomeEvent!= null) 
        { 
            SomeEvent(anObj, new EventArgs()); 
        } 
    }

    public void Method1() {
       OnSomeEvent(this);    
    }
}
于 2012-09-03T21:10:42.847 に答える
1

イベント処理の ABC は、サブスクライバーとパブリッシャーがあることを前提としています。そのため、MyClass1 がこのイベントをサブスクライブしている間に、MyClass3 にパブリック イベントが必要になる場合があります。

ただし、特定のコードでは、この複雑さは意味がありません-コールバック関数を使用する最も簡単な方法:

public static void main() { 
    MyClass1 obj = new MyClass1();
    obj.Method1();
}
public class MyClass1{
    public void Method1() {
        MyClass2 obj = new MyClass2();
        obj.Method1(MyEventHandler);
    }

    public void MyEventHandler() {
    //...
    }

}
public class MyClass2{
   public void Method1(Action callback) {
       MyClass3 obj = new MyClass3();
       obj.Method1(callback);
   }
}
public class MyClass3{
   public void Method1(Action callback) {
       // Raise event here that is handled in MyClass1?    
       callback();
   }
}
于 2012-09-03T08:05:31.700 に答える
1

物事を接続するために、イベントを中間クラスに追加できます。このようなもの:

using System;
using System.Windows.Forms;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass1 obj = new MyClass1();
            obj.Method1();
        }
    }

    public class MyClass1
    {
        public void Method1()
        {
            MyClass2 obj = new MyClass2();
            obj.SomethingHappened += somethingHappened;
            obj.Method1();
        }

        private static void somethingHappened(object sender, EventArgs e)
        {
            Console.WriteLine("Something happened!");
        }
    }

    public class MyClass2
    {
        public void Method1()
        {
            MyClass3 obj = new MyClass3();
            obj.SomethingHappened += onSomethingHappened;
            obj.Method1();
        }

        public event EventHandler SomethingHappened;

        private void onSomethingHappened(object sender, EventArgs e)
        {
            var handler = SomethingHappened;

            if (handler != null)
            {
                handler(this, e);
            }
        }
    }

    public class MyClass3
    {
        public void Method1()
        {
            onSomethingHappened();
        }

        private void onSomethingHappened()
        {
            var handler = SomethingHappened;

            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }

        public event EventHandler SomethingHappened;
    }
}

考慮すべきことの 1 つは、中間クラスの「送信者」引数をどうするかということです。(上記のコードのように) MyClass2 にするか、次のように元の送信者を保持することができます。

private void onSomethingHappened(object sender, EventArgs e)
{
    var handler = SomethingHappened;

    if (handler != null)
    {
        handler(sender, e);
    }
}
于 2012-09-03T08:15:15.510 に答える