【C#进阶】C# 委托

序号 系列文章
14 【C#进阶】C# 反射
15 【C#进阶】C# 属性
16 【C#进阶】C# 索引器

文章目录

  • 前言
  • 1、什么是委托?
  • 2、委托的定义及类型声明
  • 3、委托的实例化和使用
  • 4、多播委托的使用
  • 5、委托的属性
  • 结语

前言

大家好,我是哈桑。本章为大家介绍 C# 中的委托。


1、什么是委托?

委托是一种特殊的引用类型,是用来实现对相同参数列表和返回类型的方法的封装。 委托可以将方法作为参数传递给其他方法,也是定义回调方法1的理想选择。在实例化委托时,可以将实例与任何具有兼容签名2和返回类型的方法与其相关联。

使用委托的示例代码:(简单的实现)

using System;

public class Example
{
    // 使用delegate关键字声明委托MyDelegate 
    public delegate void MyDelegate();

    public static void MyMethod()
    {
        Console.WriteLine("Hello,delegate");
    }
	
    static void Main(string[] args)
    {
        MyDelegate m = MyMethod;
		
        // 通过委托调用方法 
        m();
    }
}

运行结果:(通过委托成功调用了自定义的方法)
【C#进阶】C# 委托_第1张图片

2、委托的定义及类型声明

委托的定义类似于方法的定义,只不过在定义的前面多加了一个 delegate 关键字。委托定义的具体内容取决于需要该委托封装引用的方法。

委托定义的示例代码:

// 使用delegate关键字声明委托MyDelegate 
public delegate void MyDelegate(int n);

在上例中,使用了 delegate 关键字定义了委托 MyDelegate。其中 MyDelegate 是一个具有公共访问属性、无返回类型、要求一个整数参数 n 的委托。(委托的定义可以按照方法定义的思路来,多加一个 delegate 关键字就行了。)

委托类型的声明一共有四种方式,其中包括使用签名匹配的方法进行声明、使用方法名进行分配、使用匿名方法、使用 lambda 表达式。

  • 使用签名匹配的方法进行声明
// 使用签名匹配的方法进行声明 
MyDelegate m = new MyDelegate(MyMethod);
  • 使用方法名进行分配
// 使用方法名进行分配 
MyDelegate m = MyMethod; 
  • 使用匿名方法3
// 使用匿名方法 
MyDelegate m = delegate ()
{
    Console.WriteLine("Hello,delegate");
};
  • 使用 lambda 表达式4
// 使用 lambda 表达式 (无参无返回值)
MyDelegate m = () => { Console.WriteLine("Hello,delegate"); };

3、委托的实例化和使用

在这里以一个新的示例来演示委托的实例化和使用

示例如下:

using System;
using static Example;

public class Example
{
    public delegate void DoSomeThing(string delName1, string delName2); 

    public static void DoWith(string doName1, string doName2, DoSomeThing callback)
    {
        Console.WriteLine($"{doName1}{doName2}一起行动了,他们一起去....");
        callback(doName1, doName2);
    }
}

public class Program
{
    public static void GoToSchool(string name1, string name2)
    {
        Console.WriteLine($"{name1}{name2}一起去学校了。");
    }

    public static void GoToExercise(string name1, string name2)
    {
        Console.WriteLine($"{name1}{name2}一起去运动了。");
    }

    static void Main()
    {
        string name1 = "小明";
        string name2 = "哈桑"; 

        DoSomeThing d1 = new DoSomeThing(GoToSchool);
        DoSomeThing d2 = new DoSomeThing(GoToExercise);

        d1(name1, name2);
        d2(name2, name1);
    }
}
  • 委托的实例化

在成功声明委托之后,就可以创建委托的实例化对象并与特定的方法相关联。 在上例中,我们使用 DoSomeThing 关键字创建了实例化对象 d1 和 d2 。

DoSomeThing d1 = new DoSomeThing(GoToSchool);
DoSomeThing d2 = new DoSomeThing(GoToExercise);
  • 委托的调用

成功创建实例化对象之后,就可以对委托对象进行传参和调用了。在上例中,对实例化对象 d1 和 d2 分别传入了参数 name1 和 name2,然后就可以开始调用。

d1(name1, name2);
d2(name2, name1);

4、多播委托的使用

多播委托又称合并委托。委托对象可以使用运算符+进行合并,注意只有相同类型的委托才可以进行合并。合并之后的委托被调用时会以合并时的顺序依次执行。同时也可以使用运算符-从多播委托删除指定的组件委托。

代码示例:

using System;

class Example
{
    delegate void CustomDel(string s);

    static void Hello(string s)
    {
        Console.WriteLine($"Hello,{s}");
    }

    static void Goodbye(string s)
    {
        Console.WriteLine($"Goodbye, {s}");
    }

    static void Main(string[] args)
    {
        CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;

        // 分别对两个个委托对象分配相同类型的方法
        hiDel = Hello; 
        byeDel = Goodbye;

        string s = "哈桑"; 
        hiDel(s);
        byeDel(s);

        Console.WriteLine("===演示多播委托的使用===");
        multiDel = hiDel + byeDel;              // 使用+运算符进行合并
        multiMinusHiDel = multiDel - byeDel;    // 使用-运算符删除委托

        multiDel(s);
        multiMinusHiDel(s); 
    }
}

在上例中,使用+运算符对 hiDel 和 byeDel 两个方法进行合并分配给了 multiDel 委托,又使用-运算符在 multiMinusHiDel 委托中删除了 byeDel 方法。

运行结果:
【C#进阶】C# 委托_第2张图片
调用委托 multiDel 时依次执行了合并时的 hiDel 和 byeDel 两个方法。因为删除了 byeDel 方法,所以 multiMinusHiDel 委托只执行了 hiDel 方法。

5、委托的属性

在 C# 中,委托的属性可以总结为以下几点:

  • 委托类似于 C++ 中的函数指针,但委托是完全面向对象且会封装对象实例和方法。
  • 委托允许将方法作为参数进行传递。
  • 委托是定义回调方法的理想选择。
  • 委托支持合并,也即一个事件调用多个方法。
  • 可以使用 lambda 表达式简化内联代码块。
  • 委托匹配的方法与委托的类型兼容即可,不必完全相同。也就是使用委托中的变体,点击了解更多。

点击了解更多委托的使用。


结语

以上就是 C# 委托的介绍啦,希望对大家有所帮助。感谢大家的支持。


  1. 回调方法: 所谓回调方法,就是把一个需要被回调的方法a作为参数传给其他方法b,这个被传入参数的方法b执行完之后又将这个方法a返回回去,这种方式称作回调方法。 ↩︎

  2. 方法签名: 由方法的名称和形参列表组成。具体来说,方法签名由它的名称以及它的形参的个数、修饰符和类型组成。 ↩︎

  3. 匿名方法: 通俗来说就是没有名字的方法,只有用于执行的方法体。匿名方法是一种传递代码块作为委托参数的方式。 ↩︎

  4. Lambda 表达式: 是一个匿名方法,可以把 lambda 表达式理解为一段可用于传递、且简洁性高、灵活的声明式风格代码。 ↩︎

你可能感兴趣的:(从基础到进阶系列,c#,开发语言,.net,微软,.netcore)