C#专题之委托

C#专题之委托

  • 一个委托基础实例
class Program
{
    static void Main(string[] args) // 程序入口
    {
        Message m = new Message(); // 创建Message对象
        Action myAction = new Action(m.PrintText); // 将方法绑定到委托
        // 这么写也可以,触发委托调用:  myAction.Invoke();
        myAction(); // 通过委托调用方法
        Console.ReadLine(); // 等待用户输入
    }
}

class Message
{
    public void PrintText() // 无参无返回值方法
    {
        Console.WriteLine("Hello!"); // 输出文本
    }
}
- Action: 专门用于封装无参数且无返回值的方法
- Action myAction = new Action(m.PrintText) 这句
	- 将 Message 类的 PrintText 方法绑定到 myAction 委托
	- 等效简写:Action myAction = m.PrintText;
- 委托调用: myAction(); // 触发实际绑定的PrintText方法
	- 相当于直接调用 m.PrintText()
  • 作用:
    • 解耦调用:委托将方法调用从直接调用转为间接调用
    • 扩展性基础:此模式是事件处理、回调机制的基础
    • 多播委托:可通过 += 绑定多个方法(此示例为单方法绑定)
  • 多播委托,先看一个声明委托的实例
namespace ConsoleApp1
{	

    // 1. 声明委托类型,void表示该委托没有返回值,而最后的()表示没有带参数(因为没传参进来)
    public delegate void NotificationHandler();

    class Program
    {
        static void Main()
        {
            // 2. 创建委托实例(此时才需要赋值)
            NotificationHandler handler = SomeMethod;

            // 3. 调用委托
            handler();
        }

        // 声明静态方法,可以直接调用,无需再创建类实例
        static void SomeMethod()
        {
            Console.WriteLine("方法被调用");
        }
    }
}
  • 多播委托示例
......
namespace ConsoleApp1
{
    
   
    internal class Program
    {
    	// 声明委托类型
        public delegate void NotificationHandler();
        static void Main(string[] args)
        {
        	
            UserService userService = new UserService();
            // 这里还有一种比较啰嗦的写法(一样的效果): 
            // NotificationHandler notifyUsers = new NotificationHandler(userService.SendEmailNotification);
            // 开始多播委托
            NotificationHandler notifyUsers = userService.SendEmailNotification;
            notifyUsers += userService.SendSmsNotification;
            notifyUsers += userService.UpdateActivityLog;
            notifyUsers += () => Console.WriteLine("【系统】所有通知发送完成!\n");

            Console.WriteLine("----- 用户注册成功 -----");
            // 执行多播委托
            notifyUsers();

            Console.WriteLine("\n----- 移除短信通知后 -----");
            // 移除其中一个委托
            notifyUsers -= userService.SendSmsNotification;
            // 再次执行
            notifyUsers();

            Console.ReadLine();

        }

    }
	
	// 声明一个业务类
    class UserService
    {
        public void SendEmailNotification()
        {
            Console.WriteLine("【邮件】已发送欢迎邮件至用户邮箱");
        }

        public void SendSmsNotification()
        {
            Console.WriteLine("【短信】已发送欢迎短信至用户手机");
        }

        public void UpdateActivityLog()
        {
            Console.WriteLine("【日志】用户注册记录已更新到数据库");
        }

    }



}

  • 委托还可以这么写
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {	
           // delegate 表示匿名函数
           Action myAction = delegate() { Console.WriteLine("Hello"); };
           // 新的流行写法,使用lam表达式
           // Action myAction = ()=> { Console.WriteLine("Hello"); };
           myAction();
           
        }
    }  
}
  • 知识点: delegate关键字在C#中有两个作用
- 声明委托类型: public delegate void NotificationHandler();
- 声明匿名函数(现推荐使用lam表达式): Action myAction = delegate() { Console.WriteLine("Hello"); };
  • Func<T>泛型类: 实现带参数的委托
......
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)

        {
            Caculatror caculatror = new Caculatror();
            // 直接调用
            caculatror.Report();
            // 委托调用
            Action myAction = new Action(caculatror.Report);
            myAction.Invoke();
            // 更简便的调用方式
            myAction();
            
            // 带参数的委托: Func<T1, T2, TResult>
            Func<int, int, int> fun1 = new Func<int, int, int>(caculatror.Add);
            Func<int, int, int> fun2 = new Func<int, int, int>(caculatror.sub);
            int x = 200;
            int y = 100;
            Console.WriteLine(fun1.Invoke(x, y));
            Console.WriteLine(fun2.Invoke(x, y));
            // 更便捷的调用
            Console.WriteLine(fun1(x, y));
		   Console.WriteLine(fun2(x, y));
            
        }

    }

    class Caculatror
    {
        public void Report()
        {
            Console.WriteLine("I have 3 methods.");
        }

        public int Add(int x, int y) {
            return x + y;
        }

        public int sub(int x, int y)
        {
            return x - y;
        }


    }

}


posted @ 2025-07-23 17:28  清安宁  阅读(19)  评论(0)    收藏  举报