前の記事では、 delegate
キーワードを使用して特定のデリゲート型を作成しました。
抽象デリゲート クラスは、疎結合と呼び出しのためのインフラストラクチャを提供します。 具象デリゲート型は、デリゲート オブジェクトの呼び出しリストに追加されるメソッドの型セーフを受け入れて適用することで、はるかに便利になります。
delegate
キーワードを使用して具体的なデリゲート型を定義すると、コンパイラはこれらのメソッドを生成します。
実際には、異なるメソッド シグネチャが必要な場合は常に新しいデリゲート型が作成されます。 この作業は、しばらくすると面倒になる可能性があります。 すべての新機能には、新しいデリゲート型が必要です。
ありがたいことに、これは必要ありません。 .NET Core フレームワークには、デリゲート型が必要な場合にいつでも再利用できるいくつかの型が含まれています。 これらは ジェネリック 定義であるため、新しいメソッド宣言が必要な場合にカスタマイズを宣言できます。
これらの型の 1 つ目は、 Action 型といくつかのバリエーションです。
public delegate void Action();
public delegate void Action<in T>(T arg);
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
// Other variations removed for brevity.
ジェネリック型引数の in
修飾子については、共分散に関する記事で説明します。
Action
など、最大 16 個の引数を含むAction<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16> デリゲートにはバリエーションがあります。
これらの定義では、デリゲート引数ごとに異なるジェネリック引数を使用することが重要です。これにより、最大限の柔軟性が得られます。 メソッド引数は同じ型である必要はありませんが、同じ型である必要があります。
void 戻り値の型を持つデリゲート型には、 Action
型のいずれかを使用します。
フレームワークには、値を返すデリゲート型に使用できるいくつかのジェネリック デリゲート型も含まれています。
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T1, out TResult>(T1 arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
// Other variations removed for brevity
結果のジェネリック型引数の out
修飾子については、共分散に関する記事で説明します。
Func
など、最大 16 個の入力引数を持つFunc<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult> デリゲートにはバリエーションがあります。
結果の型は、規則に従って、すべての Func
宣言の最後の型パラメーターになります。
値を返すデリゲート型には、 Func
型のいずれかを使用します。
また、単一の値に対するテストを返すデリゲートの特殊な Predicate<T> 型もあります。
public delegate bool Predicate<in T>(T obj);
Predicate
型の場合、構造的に同等のFunc
型が存在します。次に例を示します。
Func<string, bool> TestForString;
Predicate<string> AnotherTestForString;
これら 2 つの型は同等であると考えるかもしれません。 これらはありません。 これら 2 つの変数を同じ意味で使用することはできません。 1 つの型の変数に他の型を割り当てることはできません。 C# 型システムでは、構造体ではなく、定義された型の名前が使用されます。
.NET Core ライブラリのこれらのデリゲート型定義はすべて、デリゲートを必要とする新しい機能を作成するために新しいデリゲート型を定義する必要がないことを意味する必要があります。 これらのジェネリック定義は、ほとんどの状況で必要なすべてのデリゲート型を提供する必要があります。 必要な型パラメーターを使用して、これらの型のいずれかをインスタンス化するだけです。 ジェネリックにできるアルゴリズムの場合、これらのデリゲートはジェネリック型として使用できます。
これにより、時間を節約し、デリゲートを操作するために作成する必要がある新しい型の数を最小限に抑える必要があります。
次の記事では、実際にデリゲートを操作するための一般的なパターンをいくつか示します。
.NET