2009-03-20 11 views
15

私は、そのオブジェクトのパラメータを受け付ける関数を持つライブラリを用意したいと思います。C#のコールバック

このオブジェクトでは、Xが終了したら指定された関数を呼び出せなくてはなりません。呼び出される関数は呼び出し元によって指定され、Xはライブラリによって実行され監視されます。

どうすればいいですか?私は疑問にC#と.NET 3.5

+0

あなたの回答にdegate、events、またはその両方が含まれていると思われます。しかし、あなたの質問を数回読んだ後、私はあなたが求めているものの周りに私の頭を包むことができません。 – Brian

+1

サンプルはhttp://blog.jerrynixon.com/2011/11/there-are-lots-of-things-that-take-long.html –

答えて

38

供給デリゲートと匿名デリゲートまたはラムダ式

public static void DoWork(Action processAction) 
{ 
    // do work 
    if (processAction != null) 
    processAction(); 
} 

public static void Main() 
{ 
    // using anonymous delegate 
    DoWork(delegate() { Console.WriteLine("Completed"); }); 

    // using Lambda 
    DoWork(() => Console.WriteLine("Completed")); 
} 

か、コールバック関数のためのC#.NETで利用できるSystem.Actionを使用することができるインタフェース

public interface IObjectWithX 
{ 
    void X(); 
} 

public class MyObjectWithX : IObjectWithX 
{ 
    public void X() 
    { 
    // do something 
    } 
} 

public class ActionClass 
{ 
    public static void DoWork(IObjectWithX handlerObject) 
    { 
    // do work 
    handlerObject.X(); 
    } 
} 

public static void Main() 
{ 
    var obj = new MyObjectWithX() 
    ActionClass.DoWork(obj); 
} 
1

オブジェクトを使用しています参考

は、あなたが提供するインタフェースを実装する必要があります。インターフェイスをパラメータとして使用し、インターフェイスが公開する任意のメソッドを呼び出すことができます。さもなければ、あなたはオブジェクトが何ができるかを知る方法がありません。つまり、デリゲートをパラメータとして呼び出して呼び出すことができます。

+0

です。これは間違いありません。 – plinth

6

デリゲートのための完璧なレシピのようなサウンド - 特に、デリゲートのコールバックは、.NETの非同期パターンでの処理方法とまったく同じです。

通話者は通常、あなたに何らかの状態とデリゲートを渡して、あなたが持っている何らかのコンテキストにそれらを両方とも保存してから、デリゲートを呼び出して、その状態と結果を渡します。

状態をちょうどobjectにするか、または一般的なデリゲートを使用して、適切なタイプの状態をとることができます。その後

public delegate void Callback<T>(T state, OperationResult result) 

public void DoSomeOperation(int otherParameterForWhateverReason, 
          Callback<T> callback, T state) 

あなたは、既存のFunc<...>Action<...> デリゲート型を使用する場合がありますが、あなたはそれが明確に宣言することができます見つけることが.NET 3.5を使用しているとあなた自身の。

+2

私はあなたが代議員(そしてジェネリック、潜在的に)について読むことをお勧めします。代理人とevventsに関する私の記事はhttp://pobox.com/~skeet/csharp/eventsにあります。html –

1

操作が完了したときにあなたのライブラリが公開イベントを発生させないようにする理由はありますか?呼び出し元はイベントを処理するために登録するだけで、オブジェクトや代理人を回す心配はありません。

あなたが提供しているインターフェイスを実装しているオブジェクトはうまくいくでしょうが、それは.NETのアプローチよりJavaのアプローチのほうが多いようです。イベントは私にとって少しきれいなようです。

+0

私はイベントのやり方を知らない... – Malfist

+0

イベントについて学ぶにはhttp://pobox.com/~skeet/csharp/events.htmlを参照してください。彼らはあなたの状況に適しているかもしれないし、そうでないかもしれないが、彼らは知る価値がある。 –

-2

を使用してください。このサンプルの例を確認してください:

//Say you are calling some FUNC1 that has the tight while loop and you need to 
    //get updates on what percentage the updates have been done. 
    private void ExecuteUpdates() 
    { 
     Func1(Info => { lblUpdInfo.Text = Info; }); 
    } 

    //Now Func1 would keep calling back the Action specified in the argument 
    //This System.Action can be returned for any type by passing the Type as the template. 
    //This example is returning string. 
    private void Func1(System.Action<string> UpdateInfo) 
    { 
     int nCount = 0; 
     while (nCount < 100) 
     { 
      nCount++; 
      if (UpdateInfo != null) UpdateInfo("Counter: " + nCount.ToString()); 
      //System.Threading.Thread.Sleep(1000); 
     } 
    } 
+0

これはコールバックの代替手段ではありません。 **は**コールバックです。 – Servy

関連する問題