C#委托用法详解:定义、实例化与多播机制

码头散步
码头散步
发布时间:2026-10-16| 8人浏览过
原创

委托是C#中实现事件处理和回调机制的基础类型,它将方法封装为对象。本文系统梳理委托的定义规范、三种主要实例化方式(包括Lambda简化写法),解析Action、Func、Predicate三大内置泛型委托的应用场景,并详细说明多播委托的链式调用特性与注意事项。

1. 什么是委托

从数据结构角度理解,委托是一种用户自定义类型,其本质是对方法的抽象。它存储了一组具有相同签名(参数列表)和返回类型的方法的地址。当调用委托时,所有已注册的方法将按顺序依次执行。

2. 委托的定义

如同类需要声明一样,委托类型在使用前必须先定义。定义的语法原型如下:

delegate <返回类型> <委托名称>(<参数列表>)

示例:定义一个名为 MyDelegate 的委托,它可以指向那些返回 void 且接受一个 int 类型参数的方法:

public delegate void MyDelegate(int number);

3. 委托的实例化

定义委托类型后,需要通过实例化将其与方法关联。以下是三种常见的实例化方式:

第1步:使用 new 关键字

这是最传统的实例化方式。语法格式为:<委托类型> <变量名> = new <委托类型>(<方法名>)。

例如,通过 new 关键字将 GetSum 方法绑定到委托变量:

MyDelegate _myDelegate = new MyDelegate(GetSum);

static int GetSum(int x, int y)
{
    return x + y;
}

第2步:使用匿名方法

匿名方法允许在委托实例化时直接定义方法体,无需单独创建命名方法。语法中使用 delegate 关键字:

MyDelegate myDelegate = delegate(int x, int y)
{
    return x + y;
};

第3步:使用 Lambda 表达式

Lambda 表达式是 C# 3.0 引入的更简洁的匿名方法语法,推荐使用的方式。利用 => 操作符连接输入参数和方法体:

MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };
class Program
{
    // 声明委托
    delegate int MyDelegate(int x, int y);

    static void Main(string[] args)
    {
        // 1、使用 new 关键字
        MyDelegate _myDelegate = new MyDelegate(GetSum);

        // 2、使用匿名方法
        MyDelegate myDelegate = delegate(int x, int y)
        {
            return x + y;
        };

        // 3、使用 Lambda 表达式
        MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };
    }

    static int GetSum(int x, int y)
    {
        return x + y;
    }
}

4. 泛型委托

委托支持泛型,这使得同一个委托类型可以应用于多种不同的参数和返回类型,提高代码复用性。

泛型委托的原型结构为:delegate <委托名><T1, T2>(T1 t1)。其中 T1 通常代表输入参数类型,T2 代表返回类型。

示例:定义一个接收 int 参数并返回 bool 的泛型委托:

// 定义泛型委托
public delegate bool CheckDelegate<T>(T t);

// 使用
CheckDelegate<int> checkMod = i => (i % 2) == 0;
Console.WriteLine(checkMod(9)); // 输出 False

5. C# 内置泛型委托

C# 提供了三种常用的内置泛型委托,涵盖了大多数常见场景:

  • Action<T>:表示无返回值的方法。可以有多个输入参数,但必须没有返回值(void)。
  • Func<TResult>:表示有返回值的方法。必须指定至少一个输入参数和一个 TResult 返回类型。
  • Predicate<T>:特指返回 bool 值的委托,通常用于定义判断条件或过滤逻辑。

代码示例展示三者的用法:

namespace DelegateDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1、Action 只能委托无返回值的方法
            Action actionHello = SayHello;
            actionHello("Hello World");

            // 2、Func 委托必须有返回值的方法
            Func funcCheck = IsEven;
            Console.WriteLine(funcCheck(5)); // 输出 False

            // 3、Predicate 返回 bool 值的判断委托
            Predicate predicateCheck = IsEven;
            // 也可以使用 Lambda 简化
            Predicate predicate = p => p % 2 == 0;
            Console.WriteLine(predicateCheck(26)); // 输出 True
        }

        static void SayHello(string strMsg)
        {
            Console.WriteLine(strMsg);
        }

        static bool IsEven(int i)
        {
            return i % 2 == 0;
        }
    }
}

6. 多播委托

一个委托实例可以注册多个方法,这种机制称为多播委托。执行委托时,注册的每个方法都会按添加顺序依次调用。

第1步:注册方法

使用 += 运算符将方法追加到委托链中。注意:委托必须先通过 = 初始化至少一个方法,之后才能使用 += 注册其他方法。

MyDelegate _myDelegate = new MyDelegate(fun1); // 初始化为 fun1
_myDelegate += fun2; // 追加 fun2

第2步:解除注册

使用 -= 运算符可以将指定方法从委托链中移除:

_myDelegate -= fun2;

第3步:返回值处理

如果委托类型有返回值,调用多播委托时,返回的将是最后一个执行的方法的返回值。之前方法产生的返回值会被丢弃。若涉及异常处理,建议谨慎使用多播委托,或者手动维护委托链以捕获中间异常。

class Program
{
    delegate int MyDelegate(int x, int y);

    static void Main(string[] args)
    {
        // 注册多个方法
        MyDelegate _myDelegate = new MyDelegate(fun1);
        _myDelegate += fun2;

        // 调用委托,仅返回最后一个方法 fun2 的结果
        Console.WriteLine(_myDelegate(10, 23)); // 输出 10

        Console.ReadKey();
    }

    static int fun1(int x, int y)
    {
        return x + y; // 结果 33,被丢弃
    }

    static int fun2(int x, int y)
    {
        return x;     // 结果 10,作为最终返回值
    }
}

总结

委托是C#面向对象编程的重要基石,灵活掌握其定义、Lambda实例化以及内置泛型委托的选用,能显著提升代码的解耦程度与可读性。在处理多任务回调时,合理使用多播委托并留意其返回值特性,可避免潜在的逻辑陷阱。以上就是C#委托用法的详细内容,更多关于C#高级特性的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。