C プログラマーであれば、デリゲートを関数へのポインターとして考えることができます。ただし、C# のデリゲートは単なる関数ポインターではありません。この記事では、委任の概念と日常のプログラミングでのその使用法について説明します。
本質的に、委任はある程度の間接性を提供します。これらは、タイプセーフな方法で受け渡しおよび実行できるコードの一部をカプセル化します。動作はすぐに実行されるのではなく、オブジェクト内に含まれます。このオブジェクトに対していくつかの操作を実行できます。その 1 つは、包含された動作を実行することです。
デリゲートを使用すると、高階関数、つまり関数をパラメーターとして受け取ったり、関数を戻り値として返したりできる関数を作成できます。デリゲート型は、デリゲートが表現できるメソッド シグネチャ、特にメソッドの戻り値の型とそのパラメーターの型を定義します。次の例では、Transformer は整数を受け入れて返す任意のメソッドを表すことができるデリゲートです。
delegate int Transformer(int x);
署名を満たす任意のメソッド (ラムダ、インスタンス、静的メソッドを含む) を Transformer インスタンスに割り当てることができます。例: -
Transformer square = x => x * x; Transformer cube = x => x * x * x; Console.WriteLine(square(3)); // prints 9 Console.WriteLine(cube(5)); // prints 125
デリゲートは通常、特定の操作を実行したいコードがその操作の詳細は知らないが、その操作のインターフェイスは知っている場合に使用されます。 p>
プログラミングでは、特定の操作を実行する必要があるが、その操作を実行するためにどのメソッドを呼び出すかが事前にわからないという状況によく遭遇します。デリゲートは、動作をデリゲートに置き換えてから、コンテキストや状況に応じて適切な動作を持つデリゲートの具体的なインスタンスを渡すことで、この問題を解決するのに役立ちます。
デリゲートが何かを行うには、4 つのことが起こる必要があります -
デリゲート型は本質的に、それが表す関数の定義です。つまり、デリゲート型は、パラメーター、関数が受け入れる型、および関数が返す戻り値の型で構成されます。
たとえば、入力として 2 つの数値を受け取り、数値を返すメソッドを表すデリゲート型は、次のように宣言できます。 -
delegate int Processor(int numOne, int numTwo);
プロセッサは、クラスによって作成される型と同様の型です。 。このタイプのインスタンスを作成するには、2 つの数値を入力として受け入れ、ブール値を返すメソッドが必要です。
2) 実行されるコードはメソッドに含まれている必要があります。
上記のデリゲート型とまったく同じシグネチャを持つメソッドを定義し、実行時の状況に応じて必要な処理を実行します。たとえば、次のメソッドはいずれも 2 つの数値を受け取り、1 つの数値を返すため、Processor インスタンスの作成に使用できます。
static int Add(int numOne, int numTwo){ Return numOne + numTwo; } static int Subtract(int numOne, int numTwo){ Return numOne - numTwo; }
デリゲート型と正しいシグネチャを持つメソッドを取得したので、そのデリゲート型のインスタンスを作成できます。これを行うときは、基本的に、デリゲート インスタンスが呼び出されたときにこのメソッドを実行するように C# コンパイラーに指示します。
Processor processorOne = new Processor(Add); Processor processorTwo = new Processor(Subtract);
上の例では、デリゲート インスタンスを作成するのと同じクラスで Add メソッドと Subtract メソッドが定義されていることを前提としています。これらのメソッドが別のクラスで定義されている場合は、そのクラスのインスタンスが必要になります。
これは、当然のことながら Invoke という名前のデリゲート インスタンスのメソッドを呼び出すだけです。デリゲート インスタンスのこのメソッドは、デリゲート型宣言で指定されたものと同じパラメーター リストと戻り値の型を持ちます。 Invoke を呼び出すと、デリゲート インスタンスの操作が実行されます。
int sum = processorOne.Invoke(3, 5);
ただし、C# を使用すると、それがはるかに簡単になります。デリゲート インスタンスは、メソッド自体であるかのように直接呼び出すことができます。たとえば、
int difference = processorTwo(10, 6);
単一のデリゲート インスタンス呼び出しで一連の異なる操作を実行したい場合、C# を使用するとこれが可能になります。システム。デリゲート型には、Combine と Remove という 2 つの静的メソッドがあります。
引数として渡されたデリゲートの呼び出しリストを連結した呼び出しリストを持つ新しいデリゲートを作成します。新しいデリゲート インスタンスが呼び出されると、そのすべての操作が順番に実行されます。
public static Delegate Combine(params Delegate[] delegates); // OR public static Delegate Combine(Delegate a, Delegate b);
呼び出しリスト内のいずれかの操作で例外がスローされた場合、後続の操作は実行できなくなります。
デリゲートの呼び出しリストの最後の出現を、別のデリゲートの呼び出しリストから削除します。ソース呼び出しリストを取得し、値呼び出しリストの最後の出現を削除することによって形成された呼び出しリストを含む新しいデリゲートを返します。
public static Delegate Remove(Delegate source, Delegate value);
デリゲートは、単一メソッド インターフェイスと同様に、特定の型とパラメーターのセットを使用して動作をカプセル化します。
デリゲート型宣言によって記述された型シグネチャによって、デリゲート インスタンスと呼び出しのシグネチャの作成にどのメソッドを使用できるかが決まります。
デリゲート インスタンスを作成するには、デリゲートが呼び出されたときに実行するメソッドが必要です。
デリゲート インスタンスは文字列と同様に不変です。
各デリゲート インスタンスには、呼び出しリスト、つまり操作のリストが含まれています。
デリゲート インスタンスは、相互に結合したり、削除したりできます。
リアルタイム デモンストレーション
using System; class Program{ delegate int Transformer(int x); delegate int Processor(int numOne, int numTwo); static void Main(){ Transformer square = x => x * x; Transformer cube = x => x * x * x; Console.WriteLine(square(3)); // prints 9 Console.WriteLine(cube(5)); // prints 125 Processor processorOne = new Processor(Add); Processor processorTwo = new Processor(Subtract); int sum = processorOne.Invoke(3, 5); Console.WriteLine(sum); // prints 8 int difference = processorTwo(10, 6); Console.WriteLine(difference); // prints 4 } static int Add(int numOne, int numTwo){ return numOne + numTwo; } static int Subtract(int numOne, int numTwo){ return numOne - numTwo; } }
9 125 8 4
以上がC# の委任の概念を説明するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。