English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# Delegate (Delegate)

What if we want to pass a function as a parameter? How does C# handle callback functions or event handlers? The answer is-Delegate (Delegate). Delegate (Delegate) is a reference type variable that holds a reference to a method. The reference can be changed at runtime.

Delegates areDefine method signaturereference type data type. You can define delegate variables, just like other data types, which can refer to any method that has the same signature as the delegate.

Working with delegates involves three steps:

  1. 声明委托

  2. Set target method

  3. Invoke delegate

Delegates can be declared using the delegate keyword and function signature, as shown below.

  Delegate syntax

[access modifier] delegate [return type] [delegate name]([parameters])

The following declares a delegate named MyDelegate.

public delegate void MyDelegate(string msg);

Above, we declared a MyDelegate withvoidReturn type and string parameter. Delegates can be declared outside or inside a class. In fact, it is recommended to declare them outside the class.

After declaring a delegate, we need to set the target method or lambda expression. We can achieve this by creating a delegate object using the new keyword and passing a method that matches the delegate signature.

public delegate void MyDelegate(string msg); // 声明委托
//Set target method
MyDelegate del = new MyDelegate(MethodA);
// Or
MyDelegate del = MethodA; 
// or lambda expression 
MyDelegate del = (string msg) => Console.WriteLine(msg);
// Target method
static void MethodA(string message)
{
    Console.WriteLine(message);
}

You can set the target method by directly assigning a method without creating an object of the delegate, for example, MyDelegate del = MethodA.

After setting the target method, you can use the Invoke() method or use the () operator to invoke the delegate.

del.Invoke("Hello World!");
//Or 
del("Hello World!");

The following is a complete example of a delegate.

public delegate void MyDelegate(string msg); //声明委托
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del = ClassA.MethodA;
        del("Hello World");
        del = ClassB.MethodB;
        del("Hello World");
        del = (string msg) => Console.WriteLine("Called lambda expression: ") + msg);
        del("Hello World");
    }
}
class ClassA
{
    static void MethodA(string message)
    {
        Console.WriteLine("Called ClassA.MethodA() with parameter: ") + message);
    }
}
class ClassB
{
    static void MethodB(string message)
    {
        Console.WriteLine("Called ClassB.MethodB() with parameter: ") + message);
    }
}

The following diagram illustrates the delegate.

C# delegate

Passing a delegate as a parameter

Methods can have delegate type parameters, as shown below.

public delegate void MyDelegate(string msg); //声明委托
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del = ClassA.MethodA;
        InvokeDelegate(del);
        del = ClassB.MethodB;
        InvokeDelegate(del);
        del = (string msg) => Console.WriteLine("Called lambda expression: ") + msg);
        InvokeDelegate(del);
    }
    static void InvokeDelegate(MyDelegate del) // MyDelegate type parameters
    {
        del("Hello World");
    }
}
class ClassA
{
    static void MethodA(string message)
    {
        Console.WriteLine("Called ClassA.MethodA() with parameter: ") + message);
    }
}
class ClassB
{
    static void MethodB(string message)
    {
        Console.WriteLine("Called ClassB.MethodB() with parameter: ") + message);
    }
}

In .NET, Func and Action types are built-in generic delegates and should be used for the most common delegates, rather than creating new custom delegates.

Multicast delegate

A delegate can point to multiple methods. A delegate that points to multiple methods is called a multicast delegate.+" or "+The assignment operator adds a function to the call list, while "-" and "-The assignment operator removes it.

public delegate void MyDelegate(string msg); //Declare a delegate
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del1 = ClassA.MethodA;
        MyDelegate del2 = ClassB.MethodB;
        MyDelegate del = del1 + del2; // del1 + del2
        del("Hello World");
        MyDelegate del3 = (string msg) => Console.WriteLine("Called lambda expression: ") + msg);
        del +=3; // del1 + del2 + del3
        del("Hello World");
        del = del - del2; // Remove del2
        del("Hello World");
        del -=1 // Remove del1
        del("Hello World");
    }
}
class ClassA
{
    static void MethodA(string message)
    {
        Console.WriteLine("Called ClassA.MethodA() with parameter: ") + message);
    }
}
class ClassB
{
    static void MethodB(string message)
    {
        Console.WriteLine("Called ClassB.MethodB() with parameter: ") + message);
    }
}

加法和减法运算符始终作为赋值的一部分工作:del1+=del2;与del1=del1+del2完全等价;减法也是如此。

如果委托返回一个值,那么当多播委托调用时,最后分配的目标方法的值将被返回。

public delegate int MyDelegate(); //声明委托
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del1 = ClassA.MethodA;
        MyDelegate del2 = ClassB.MethodB;
        MyDelegate del = del1 + del2; 
        Console.WriteLine(del());// 返回200
    }
}
class ClassA
{
    static int MethodA()
    {
        return 100;
    }
}
class ClassB
{
    static int MethodB()
    {
        return 200;
    }
}

泛型委托

可以使用与委托相同的方式定义泛型委托,但可以使用泛型type参数或返回类型。 设置目标方法时,必须指定泛型类型。

例如,看以下用于int和string参数的通用委托。

public delegate T add<T>(T param1, T param2); // 泛型委托
class Program
{
    static void Main(string[] args)
    {
        add<int> sum = Sum;
        Console.WriteLine(sum(10, 20));
        add<string> con = Concat;
        Console.WriteLine(conct("Hello ","World!!"));
    }
    public static int Sum(int val1, int val2)
    {
        return val1 + val2;
    }
    public static string Concat(string str1, string str2)
    {
        return str1 + str2;
    }
}

委托还用于声明事件和匿名方法。

 要记住的要点

  1. 委托是定义签名的引用类型数据类型。

  2. 委托类型变量可以引用具有与委托相同签名的任何方法。

  3. 语法:[访问修饰符]委托[返回类型] [委托名称]([参数])([access modifier] delegate [return type] [delegate name]([parameters]))

  4. The signature of the target method must match the delegate signature.

  5. Delegates can be called like a regular function or invoke() method.

  6. You can use " +" or " + The '=' operator assigns multiple methods to a delegate and uses "-" or "-The '=' operator removes it. It is called a multicast delegate.

  7. If a multicast delegate returns a value, it returns the value from the last assigned target method.

  8. Delegates are used to declare events and anonymous methods in C#.