20250606-C#知识:委托和事件

C#知识:委托和事件

使用委托可以很方便地调用多个方法,也方便将方法作为参数进行传递


1、委托

  • 委托是方法的容器
  • 委托可以看作一种特殊的类
  • 先定义委托类,再用委托类声明委托变量,委托变量可以存储方法
csharp 复制代码
delegate int Calculate(int a, int b);
csharp 复制代码
Calculate calculate;
calculate = Add;
csharp 复制代码
calculate(5, 3);
  • 委托可以存储多个方法
csharp 复制代码
calculate = Add;
calculate += Sub;
calculate += Mul;
  • 委托必须先赋值,然后使用+=添加方法或使用-=删除方法
  • 删除方法,可以随机删除方法
csharp 复制代码
calculate -= Add;
calculate(5, 3);
//清空
calculate = null;
  • 委托可以有泛型
csharp 复制代码
delegate T CalculatePlus<T>(T a, T b);
csharp 复制代码
CalculatePlus<int> calculatePlus;
calculatePlus = Add;
calculatePlus(6, 2);
  • 系统提供了两种委托Action和Func
  • 系统提供的委托支持泛型,一般够用
  • 无返回值Action
csharp 复制代码
Action<string> myAction = Speak;
myAction.Invoke("Sleep is fine");
  • 有返回值Func,最后一个泛型参数为返回类型
csharp 复制代码
Func<float, int, string> myFunc = Move;
myFunc(100, 6);

2、事件

  • 青春迷你版委托(受限制的委托)
  • 创建委托变量时在前面加上event关键字
csharp 复制代码
public event Action<string> myEvent;
  • 与委托相比,不能在创建事件变量的类外赋值和调用
  • 使用事件更安全
  • 事件只能作为成员存在于类、接口和结构体中
csharp 复制代码
class TestEvent
{
    public Action<string> myDelegate;
    public event Action<string> myEvent;

    public void InitializeEvent()
    {
        myEvent = null;
    }
}
csharp 复制代码
TestEvent testEvent = new TestEvent();
//testEvent.myEvent = Speak;    //报错
testEvent.myDelegate = Speak;

testEvent.InitializeEvent();
testEvent.myEvent += Speak;

//testEvent.myEvent("歪比巴卜");    //报错
testEvent.myDelegate("Ohhhhhhhhhh no!");

3、完整代码示例

csharp 复制代码
namespace LearnDelegateAndEvent
{
    delegate int Calculate(int a, int b);
    delegate T CalculatePlus<T>(T a, T b);

    class TestEvent
    {
        public Action<string> myDelegate;
        public event Action<string> myEvent;

        public void InitializeEvent()
        {
            myEvent = null;
        }
    }
    internal class Program
    {

        static int Add(int a, int b)
        {
            int result = a + b;
            Console.WriteLine($"ADD:{result}");
            return result;
        }

        static int Sub(int a, int b)
        {
            int result = a - b;
            Console.WriteLine($"SUB:{result}");
            return a - b;
        }

        static int Mul(int a, int b)
        {
            int result = a * b;
            Console.WriteLine($"MUL:{result}");
            return a * b;
        }

        static void Speak(string word)
        {
            Console.WriteLine($"I want to say {word}");
        }

        static string Move(float speed, int seconds)
        {
            string result = $"Move:{speed * seconds}";
            Console.WriteLine(result);
            return result;
        }

        static void Main(string[] args)
        {
            //委托按照添加顺序执行方法
            Calculate calculate;
            //添加方法
            calculate = Add;
            calculate += Sub;
            calculate += Mul;

            calculate(1, 2);

            //删除方法,可以随机删除方法
            calculate -= Add;
            calculate(5, 3);
            calculate = null;

            //泛型委托
            CalculatePlus<int> calculatePlus;
            calculatePlus = Add;
            calculatePlus(6, 2);

            //系统委托
            Action<string> myAction = Speak;
            myAction.Invoke("Sleep is fine");
            //有返回值,最后一个泛型参数为返回类型
            Func<float, int, string> myFunc = Move;
            myFunc(100, 6);



            Console.WriteLine("==========================");



            //事件
            TestEvent testEvent = new TestEvent();
            //testEvent.myEvent = Speak;    //报错
            testEvent.myDelegate = Speak;

            testEvent.InitializeEvent();
            testEvent.myEvent += Speak;

            //testEvent.myEvent("歪比巴卜");    //报错
            testEvent.myDelegate("Ohhhhhhhhhh no!");
        }
    }
}

输出:

csharp 复制代码
ADD:3
SUB:-1
MUL:2
SUB:2
MUL:15
ADD:8
I want to say Sleep is fine
Move:600
==========================
I want to say Ohhhhhhhhhh no!

4、参考资料

  1. 《唐老狮C#》

本文结束,感谢您的阅读~

相关推荐
汉字萌萌哒4 分钟前
2024CSP-J入门级C++真题详解
开发语言·c++
arbboter15 分钟前
【网络工具】NetProxy网络代理用户手册
开发语言·网络·c#·网络代理·网络异常·代理工具
微小冷1 小时前
海康威视相机C#二次开发环境配置
数码相机·c#·.net·海康威视·相机开发
汉字萌萌哒1 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
叠层归一研究院1 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
小雨笙笙2 小时前
C语言:变量三属性——存储类型
c语言·开发语言
果果燕2 小时前
C++ 学习笔记(二):类与对象—— 构造函数与析构函数
开发语言·c++
江畔柳前堤2 小时前
Function Calling 与 Tool Calling:从认知到工程的全景深度解析
开发语言·网络·人工智能·深度学习·算法·机器学习·php
2601_949950633 小时前
Java 面试准备,用练题簿把“背过八股”变成“真正会答”
java·开发语言·面试·刷题·小程序推荐
老洋葱Mr_Onion3 小时前
【C++】信息学奥赛CSP通关之路——CSP-J/S第一轮原创全真模拟试卷集(2026)卷四全卷解析
开发语言·c++