パラメータのオブジェクトを受け入れる関数を含むライブラリが必要です。
このオブジェクトを使用して、Xが終了したときに指定された関数を呼び出せるようにします。呼び出される関数は呼び出し元によって指定され、Xはライブラリによって実行および監視されます。
これどうやってするの?
参考までに、C#と.NET3.5を使用しています
2 つのオプション:
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"));
}
コールバックに何かを渡す必要がある場合は、次のように型パラメーターを使用できますAction
。
public static void DoWork(Action<string> processAction)
{
// do work
if (processAction != null)
processAction("this is the string");
}
public static void Main()
{
// using anonymous delegate
DoWork(delegate(string str) { Console.WriteLine(str); });
// using Lambda
DoWork((str) => Console.WriteLine(str));
}
複数の引数が必要な場合は、型パラメータを に追加できますAction
。戻り値の型が必要な場合は、前述Func
のように戻り値の型を最後の型パラメーターとして使用します (Func<string, int>
は文字列を受け取り、int を返す関数です)。
デリゲートの詳細については、こちらをご覧ください。
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);
}
デリゲートの完璧なレシピのように聞こえます。特に、デリゲートを使用したコールバックは、.NETの非同期パターンでこれが処理される方法とまったく同じです。
呼び出し元は通常、いくつかの状態とデリゲートを渡します。両方を取得したコンテキストに格納してから、デリゲートを呼び出して、状態と結果を渡します。
object
状態を正しくするか、潜在的にジェネリックデリゲートを使用して、適切なタイプの状態を取得することができます。
public delegate void Callback<T>(T state, OperationResult result)
それで:
public void DoSomeOperation(int otherParameterForWhateverReason,
Callback<T> callback, T state)
.NET 3.5を使用しているので、既存の型Func<...>
とAction<...>
デリゲート型を使用したい場合がありますが、独自の型を宣言する方が明確な場合があります。(名前によって、使用目的が明確になる場合があります。)
問題のオブジェクトは、ユーザーが提供するインターフェースを実装する必要があります。インターフェイスをパラメータとして使用すると、インターフェイスが公開する任意のメソッドを呼び出すことができます。そうしないと、オブジェクトの機能を知る方法がありません。または、デリゲートをパラメーターとして取り、それを呼び出すことができます。
操作が完了したときに発生する公開イベントをライブラリに提供させない理由はありますか?そうすれば、発信者はイベントを処理するために登録するだけで済み、オブジェクトやデリゲートを渡すことを心配する必要はありません。
提供したインターフェースを実装するオブジェクトは機能しますが、.NETアプローチよりもJavaアプローチのようです。イベントは私には少しきれいに思えます。