Ombud med namngivna kontra anonyma metoder (C#-programmeringsguide)
Ett ombud kan associeras med en namngiven metod. När du instansierar ett ombud med hjälp av en namngiven metod skickas metoden som en parameter, till exempel:
// 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;
Detta anropas med hjälp av en namngiven metod. Ombud som skapats med en namngiven metod kan kapsla in antingen en statisk metod eller en instansmetod. Namngivna metoder är det enda sättet att instansiera ett ombud i tidigare versioner av C#. Men i en situation där det är oönskat att skapa en ny metod kan du med C# instansiera ett ombud och omedelbart ange ett kodblock som ombudet ska bearbeta när det anropas. Blocket kan innehålla antingen ett lambda-uttryck eller en anonym metod.
Den metod som du skickar som en delegatparameter måste ha samma signatur som ombudsdeklarationen. En ombudsinstans kan kapsla in antingen statisk metod eller instansmetod.
Kommentar
Även om ombudet kan använda en out-parameter rekommenderar vi inte att det används med multicast-händelsedelegater eftersom du inte kan veta vilket ombud som ska anropas.
Från och med C# 10 har metodgrupper med en enda överlagring en naturlig typ. Det innebär att kompilatorn kan härleda returtypen och parametertyperna för ombudstypen:
var read = Console.Read; // Just one overload; Func<int> inferred
var write = Console.Write; // ERROR: Multiple overloads, can't choose
Exempel
Följande är ett enkelt exempel på hur du deklarerar och använder ett ombud. Observera att både ombudet , MultiplyCallback
och den associerade metoden , MultiplyNumbers
har samma signatur
// 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
*/
I följande exempel mappas ett ombud till både statiska metoder och instansmetoder och returnerar specifik information från var och en.
// 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.
*/