3
public Class A
{

   public A()
   {
     someotherclass.someevent += new EventHandler(HandleEvent);
   }

   private void HandleEvent(object sender,CustomEventArgs e) 
   {
      if(e.Name == "Type1")
           Method1();
      else if(e.Name == "Type2")
           Method2();
   }

   protected virtual void Method1(){}
   protected virtual void Method2(){}
}

public class B: A
{
   public B()
   { /*Something*/}

   protected override void Method1(){/*some logic*/}
   protected override void Method2(){/*some other logic*/}
}

public class C: A
{
   public C()
   { /*Something*/}

   protected override void Method1(){/*some logic*/}
   protected override void Method2(){/*some other logic*/}
}

public class Main
{
    private A;

    public Main(){/*Something*/}

    private void StartB()
    {
       A = new B();
    } 

    private void StartC()
    {
       A = new C();
    } 
}

ここで、メソッドStartB (最初に呼び出される) とStartC (2 番目に呼び出される)の両方が呼び出されるサイクルを経た後、 someeventがトリガーされると、コードはクラス Bでメソッドを実行しようとします(そしてそれ以降)。クラス C のメソッドを呼び出すとエラーが発生するため、そこに到達できませんでした) 代わりに、クラス Cのメソッドのみを呼び出します。

イベントはコンストラクターでサブスクライブされるため、StartB の呼び出しで最初にサブスクライブされるため、クラス B メソッドはまだ起動されていると思います。

質問:
最新のインスタンス化されたクラスのメソッドのみを実行する必要があります。

例: StartBStartCが順番に呼び出された場合、何らかのイベントがトリガーされたときに、クラス Cのメソッドのみが実行されます。逆も同じ。どうやってするか?

私は何かひどく間違ったことをしていることを知っています。どんな助けでも大歓迎です。

4

2 に答える 2

3

最初のインスタンスからイベントのサブスクライブを解除していないため、呼び出されます。呼び出されたくない場合は、購読を解除する必要があります。あなたはこのようなことをすることができます

class A
{

private static EventHandler lastHandler;

public A()
{
    //warning, not thread safe
    if(lastHandler != null)
    {
        someotherclass.someevent -= lastHandler;
    }
    lastHandler = new EventHandler(HandleEvent);
    someotherclass.someevent += lastHandler;
}

しかし、それはかなりハッキーなようです。IDisposable新しいインスタンスを作成する前に、最後のインスタンスをクリーンアップするメソッド (例: ) を実装する方がよいでしょう。

于 2011-11-17T09:01:13.000 に答える
1

私があなたを正しく理解していれば、startC が呼び出された後に B のメソッドが呼び出されていると言っていますが、これが起こることを望んでいませんか?

あなたの問題は、someotherclassが静的クラスであるか、作成されたすべてのBとCの間でインスタンスが何らかの形で共有されていることだと思います-その場合、新しいクラスを作成するときにsomeotherclass.someeventから古いイベントハンドラーを登録解除する必要があります. ハンドラーを登録解除しない場合、someotherclass オブジェクトは、それに登録された B または C オブジェクトへの参照を持つことになります。そのため、メイン クラスで参照を上書きしても、オブジェクトは、イベントがトリガーされたときにまだ呼び出されています。

于 2011-11-17T09:02:01.800 に答える