C#委托详解

C#中的委托

C# 中的delegate、event、Action、Func都属于委托,只是展现的形式不同而已,无论哪种,其实都可以采用delegat实现

利用委托发布订阅模式可以实现观察者模式 – 传送门

  • delegate是很宽泛的,格式内容都不受限,俗话说没有规矩不成方圆,如果一人过于随意,那么他所做的事也规范不到哪去,这就会导致后期的维护很费劲,实际开发中也基本都用后面三种。

区别:

delegate:
至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型。

Action:无返回值的泛型委托。

Action: 表示无参,无返回值的委托
Action<int,string> 表示有传入参数int,string无返回值的委托
Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托
Action<int,int,int,int> 表示有传入4int型参数,无返回值的委托
Action至少0个参数,至多16个参数,无返回值。

Func:有返回值的泛型委托

Func<int>
表示无参,返回值为int的委托
Func<object,string,int>
表示传入参数为object, string 返回值为int的委托
Func<object,string,int>
表示传入参数为object, string 返回值为int的委托

Func<T1,T2,T3,int>
表示传入参数为T1,T2,T3(泛型)返回值为int的委托

Func至少0个参数,至多16个参数,根据返回值泛型返回。
必须有返回值,不可void

event:事件,修饰委托

event关键修饰的委托,只能在该类中调用,主要用于封装安全。

用法示例

public class Dog {
        public event Action HelloEvent;
        public void SayHello()
        {
            HelloEvent();
        }
    }
    
外部代码:
            Dog dog = new Dog();
            dog.HelloEvent += say1;
            dog.SayHello();
        static void say1()
        {
            Console.WriteLine("say1");
        }

使用委托可以实现类似多态功能:

     static string ToUpper(string str)
    {
        return str.ToUpper();
    }
    static string ToLower(string str)
    {
        return str.ToLower();
    }
    static string ToStar(string str)
    {
        return str + "星";
    }
        
    static void DealString(Func<string, string> dealFunc,string str)
    {
        Console.WriteLine(dealFunc(str));
    }
        DealString(ToUpper, "Abc");
        DealString(ToLower, "aBc");
        DealString(ToStar, "Abc");

简易示例代码1

using System;
using System.Collections.Generic;

namespace Cat
{
    class Cat
    {
        string _name = "";

        public Cat(string name)
        {
            _name = name;
        }
        /// <summary>
        /// 委托
        /// </summary>
        public delegate void CatHellEventHandler();

        /// <summary>
        /// 事件 类型=委托类型 可以使用 += -= 类外不能使用。
        /// </summary>
        public event CatHellEventHandler CatHell;

        /// <summary>
        /// 委托对象 类型=委托类型 类外可以使用
        /// </summary>
        public CatHellEventHandler CatHell1;

        public void hell()
        {
            Console.WriteLine("{0}: i`m coming!", _name);

            if(CatHell != null)//event对象-事件为了封装安全,只能在类内使用
			{
                CatHell();//如果有对象登记事件,则执行!
			}

            //简化调用 CatHell?为可空类型
            // CatHell?.Invoke(); 

        }
    }

    class Mouse
    {
        string _name = "";

        public Mouse(string name)
        {
            _name = name;
        }

        public void Run()
        {
            Console.WriteLine("{0}: we are runing!", _name);
        }
    }

    class Program
	{
        static void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

        static void Main(string[] args)
		{
            //运算符测试 ^ ..
            int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
            int[] subset = numbers[1..(4)];//不包含4范围
            Display(subset);  // output: 10 20 30

            int i = numbers[^1];//最后一个元素
			Console.WriteLine(i);

            int[] inner = numbers[1..^1];//不包含arr-1=50范围
            Display(inner);  // output: 10 20 30 40

            string line = "one two three";
            Range endIndices = ^5..^0;
            string end = line[endIndices];
            Console.WriteLine(end);  // output: three

            Console.WriteLine("Hello World!");

            Cat cat = new Cat("tom");

            Mouse mouse1 = new Mouse("jerry");
            Mouse mouse2 = new Mouse("jerry1");

            //事件对象CatHell 类内调用
            //只能在类内使用,类外只能出现在 += -= 的左边
            cat.CatHell += new Cat.CatHellEventHandler(mouse1.Run);
            cat.hell();
            //cat.CatHell(); 无法调用

            //委托对象CatHell1 类外调用
            cat.CatHell1 += new Cat.CatHellEventHandler(mouse1.Run);
            cat.CatHell1 += new Cat.CatHellEventHandler(mouse2.Run);
            //调用方法1
            cat.CatHell1.Invoke();

            //调用方法2
            cat.CatHell1();

            Console.ReadLine();


        }
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值