Delegáti s pojmenovanými vs. anonymními metodami (Průvodce programováním v C#)
Delegáta lze přidružit k pojmenované metodě. Když vytvoříte instanci delegáta pomocí pojmenované metody, metoda se předá jako parametr, například:
// Declare a delegate.
delegate void WorkCallback(int x);
// Define a named method.
void DoWork(int k) { /* ... */ }
// Instantiate the delegate using the method as a parameter.
WorkCallback d = obj.DoWork;
Tato metoda se volá pomocí pojmenované metody. Delegáti vytvořené pojmenovanou metodou mohou zapouzdřovat statickou metodu nebo metodu instance. Pojmenované metody představují jediný způsob, jak vytvořit instanci delegáta v dřívějších verzích jazyka C#. V situaci, kdy je vytvoření nové metody nežádoucí režie, však jazyk C# umožňuje vytvořit instanci delegáta a okamžitě zadat blok kódu, který bude delegát zpracovávat při jeho zavolání. Blok může obsahovat výraz lambda nebo anonymní metodu.
Metoda, kterou předáte jako parametr delegáta, musí mít stejný podpis jako deklarace delegáta. Instance delegáta může zapouzdřovat statickou metodu nebo metodu instance.
Poznámka:
Přestože delegát může použít výstupní parametr, nedoporučujeme jeho použití s delegáty událostí vícesměrového vysílání, protože nevíte, který delegát bude volána.
Počínaje jazykem C# 10 mají skupiny metod s jedním přetížením přirozený typ. To znamená, že kompilátor může odvodit návratový typ a typy parametrů pro typ delegáta:
var read = Console.Read; // Just one overload; Func<int> inferred
var write = Console.Write; // ERROR: Multiple overloads, can't choose
Příklady
Následuje jednoduchý příklad deklarace a použití delegáta. Všimněte si, že delegát i MultiplyCallback
přidružená metoda MultiplyNumbers
mají stejný podpis.
// Declare a delegate
delegate void MultiplyCallback(int i, double j);
class MathClass
{
static void Main()
{
MathClass m = new MathClass();
// Delegate instantiation using "MultiplyNumbers"
MultiplyCallback d = m.MultiplyNumbers;
// Invoke the delegate object.
Console.WriteLine("Invoking the delegate using 'MultiplyNumbers':");
for (int i = 1; i <= 5; i++)
{
d(i, 2);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
// Declare the associated method.
void MultiplyNumbers(int m, double n)
{
Console.Write(m * n + " ");
}
}
/* Output:
Invoking the delegate using 'MultiplyNumbers':
2 4 6 8 10
*/
V následujícím příkladu je jeden delegát mapován na statické i instance metody a vrací konkrétní informace z každého.
// Declare a delegate
delegate void Callback();
class SampleClass
{
public void InstanceMethod()
{
Console.WriteLine("A message from the instance method.");
}
static public void StaticMethod()
{
Console.WriteLine("A message from the static method.");
}
}
class TestSampleClass
{
static void Main()
{
var sc = new SampleClass();
// Map the delegate to the instance method:
Callback d = sc.InstanceMethod;
d();
// Map to the static method:
d = SampleClass.StaticMethod;
d();
}
}
/* Output:
A message from the instance method.
A message from the static method.
*/