1

私はCまたはC++の些細な問題の解決策を数日間探していましたが、C#では不可能に見えます。

別のプログラマーがクラスAを作成します。クラスAのイベントハンドラーメソッドは、イベントを処理するためにクラスBのメソッドを呼び出す必要があります。イベントのタイプに応じて、クラスBのそのメソッドはクラスAのメソッドをコールバックする必要があり、そのメソッドは任意の名前を持っているか、存在しない場合もあります。

これはCでは簡単です。コールバック関数へのポインタがあり、nullでない場合は間接的に呼び出します。C#で間接的なメソッド呼び出しを行う方法がわかりません。これは、問題を説明するコードの例です。

public class A: ZZZ { // this class is NOT under my control
   private b = new B(this);

   public void myCallback(C x) {
      // do something
   }

   // Elsewhere in the application expects a protected
   // override method to exist in *this* class A to handle
   // an event. But we want a method in class B to handle
   // it and then call myCallback depending on the type of event

   protected override void handle_some_event(event e) {
      // doesn't work -- how do I pass a "pointer" to the callback??
      b.handle_event(e, myCallback);
   }
}


public class B {    // this class IS under my control
   private A base;

    public B(A a) {
       base = a; // allows for calling methods in class A from class B
    }

    public handle_event(event e, ??? callback pointer ??? cback) {
       // do stuff...
       // then do the callback
       // cback(); // this won't work
       base.myCallback(); // this WILL work but only if I hard-code "myCallback"
    }    
}

問題は、クラスBが私が書いているものであり、クラスAが私のクラスBを使用する他の誰かによって作成されていることです。他の誰かがコールバックをまったく定義しないか、任意のコールバックを作成するオプションがあります。名前。クラスBは、それが何であるか、そしてそれにアクセスする方法をどういうわけか知る必要があります。CまたはC++では、他のプログラマーは自分のコールバック関数へのポインターを渡すだけで済みます。それはC#で可能ですか?

4

3 に答える 3

2

あなたはあなたに渡すことを望みますあなたはこのようにそれをAction<T>するhandle_some_eventことができます:

public handle_some_event(event e, Action<C> cback) 
{
   // Do stuff
   if(cback != null)
       cback(myC);
}

実際、あなたclass Bは何も知る必要はありませんclass A。実行するにはアクションデリゲートが必要です。残りは関係ありません。

于 2012-06-19T01:57:41.957 に答える
0

アクションデリゲートを使用して、コールバックを参照できます。

詳細については、次のURLを確認してください:http://msdn.microsoft.com/en-us/library/018hxwa8.aspx

クラスBを次のように変更します。publicclassB{private A base;

    public B(A a) {
       base = a; // allows for calling methods in class A from class B
    }

   //#################### NOTE THE CHANGE HERE ##################//
    public handle_some_event(event e, Action<C> cback) {
       // do stuff...
       // then do the callback
       cback(x); // this will work assuming you have x defined somewhere in B
    }    
}
于 2012-06-19T01:55:02.317 に答える
0

これが私の最初の投稿のコードに基づいて、私が最終的に得た解決策です

public class A: ZZZ { // this class is NOT under my control
   private b = new B(this);
   b.UserCallback = myCallback;

   static void myCallback(C x) {
      // do something
   }

   // Elsewhere in the application expects a protected
   // override method to exist in *this* class A to handle
   // an event. But we want a method in class B to handle
   // it and then call myCallback depending on the type of event

   protected override void handle_some_event(event e) {
      b.handle_event(e);
   }
}

public delegate void usercallback(Z z); // declare OUTSIDE both classes

public class B {    // this class IS under my control
   public usercallback UserCallback = defaultCallback;
   static void defaultCallback(Z z) { /* do nothing */ }

   public handle_event(event e) {
       // do stuff...
       // then do the callback
       UserCallback(z);
   }    
}

しばらくの間私を悩ませたのは、デリゲート宣言がC関数のプロトタイプに類似しており、デリゲートがクラスの宣言型として使用される可能性があるという事実に頭を悩ませていることです。

于 2012-06-22T00:16:39.010 に答える