Delegaty z metodami nazwanymi lub anonimowymi (Przewodnik programowania w języku C#)
Delegat może być skojarzony z nazwaną metodą. Podczas tworzenia wystąpienia delegata przy użyciu nazwanej metody metoda jest przekazywana jako parametr, na przykład:
// 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;
Jest to wywoływane przy użyciu nazwanej metody. Delegaty skonstruowane z nazwaną metodą mogą hermetyzować metodę statyczną lub metodę wystąpienia. Metody nazwane to jedyny sposób tworzenia wystąpienia delegata we wcześniejszych wersjach języka C#. Jednak w sytuacji, w której utworzenie nowej metody jest niepożądanym obciążeniem, język C# umożliwia utworzenie wystąpienia delegata i natychmiastowe określenie bloku kodu, który delegat będzie przetwarzał po wywołaniu. Blok może zawierać wyrażenie lambda lub metodę anonimową.
Metoda przekazywana jako parametr delegata musi mieć ten sam podpis co deklaracja delegata. Wystąpienie delegata może hermetyzować metodę statyczną lub wystąpienie.
Uwaga
Mimo że delegat może użyć parametru out , nie zalecamy jego użycia z delegatami zdarzeń multiemisji, ponieważ nie można wiedzieć, który delegat zostanie wywołany.
Począwszy od języka C# 10, grupy metod z pojedynczym przeciążeniem mają typ naturalny. Oznacza to, że kompilator może wywnioskować typ zwracany i typy parametrów dla typu delegata:
var read = Console.Read; // Just one overload; Func<int> inferred
var write = Console.Write; // ERROR: Multiple overloads, can't choose
Przykłady
Poniżej przedstawiono prosty przykład deklarowania i używania delegata. Zwróć uwagę, że zarówno delegat, MultiplyCallback
, jak i skojarzona metoda MultiplyNumbers
, mają ten sam 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
*/
W poniższym przykładzie jeden delegat jest mapowany na metody statyczne i wystąpienia i zwraca określone informacje z każdego z nich.
// 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.
*/