Creating an algorithm where the caller also supplies at least one method that implements part of the algorithm
In this system, when a payment is processed, different notification mechanisms need to be executed: like sending an email notification, logging the transaction, and updating the user account status. We can use delegates to handle these actions, allowing for a flexible and extensible way to plug in different types of notifications.
Encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter
Encapsulates a method that has no parameters and does not return a value
// declare a delegate
public delegate void MyCalculate(int a, int b);
// set target method
MyCalculate del = new MyDelegate(MethodA);
// or MyCalculate del = MethodA;
// or set lambda expression
MyCalculate del = (int a, int b) => Console.WriteLine( msg );
// target method
static void MethodA(int a, int b)
{ Console.WriteLine($"a+b= {a+b}"); }
// Create the payment processor
PaymentProcessor paymentProcessor = new PaymentProcessor();
// Register methods to the delegate
paymentProcessor.PaymentProcessed += notificationService.SendEmailNotification;
paymentProcessor.PaymentProcessed += loggerService.LogTransaction;
paymentProcessor.PaymentProcessed += accountService.UpdateUserAccount;
// Process the payment
paymentProcessor.ProcessPayment(100.50);
public static Func<int, int, string> MyCalculate;
// set target method
MyCalculate del = MethodA;
// target method
static string MethodA(int a, int b)
{ return $"a+b= {a+b}"; }
// Delegate using Action<int, int>
Acion<int, int> del = MethodA;
// target method
static void MethodA(int a, int b)
{ Console.WriteLine($"a+b= {a+b}"); }
Implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves assignment compatibility and contravariance reverses it.
Covariance enables you to pass a derived type where a base type is expected
// Assignment compatibility.
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;
// Covariance.
IEnumerable<string> strings = new List<string>();
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;
// Contravariance.
// Assume that the following method is in the class:
static void SetObject(object o) { }
Action<object> actObject = SetObject;
// An object that is instantiated with a less derived type argument
// is assigned to an object instantiated with a more derived type argument.
// Assignment compatibility is reversed.
Action<string> actString = actObject;