C#深入学习--委托

一、基本概念

有过买二手房交易的朋友都有感触,办理过户等等一系列手续都是相当麻烦的,这个时候,房产中介出现了,我们只需要将必备资料交个中介,他们就会帮忙办理的妥妥的,我们并不需要关系整个办理过程,这个过程就是委托,委托房产中介办理相关手续。再入,我们用的苹果手机,也并不是苹果公司直接生产,也是委托代工厂进行生产,下面就通过苹果手机的代理生产过程解析委托。

二、苹果手机代工过程

2.1 苹果公司定义好本次手机的生产规格(定义委托)传入生产规格,返回手机

public class Phone
    {
        /// <summary>
        /// 定义委托,传入生产规格,返回一个符合规格的手机
        /// </summary>
        /// <param name="space"></param>
        /// <returns></returns>
        public delegate string CreateIPhone11(string space);

        //等待代工厂加入
        public CreateIPhone11 createIPhone11 = null;

        /// <summary>
        /// 发布开始生产指定
        /// </summary>
        public void IPhone11Create()
        {
            if(createIPhone11!=null)
            {
                //通知代理厂进行生产
                Console.WriteLine($"新款IPhone【{createIPhone11.Invoke("6.1寸")}】");
            }
        }
    }

2.2 代工厂制定一套方案,可以满足苹果公司的要求

    public class Foxconn
    {
        public string FoxconnIphon11(string space)
        {
            //一系列逻辑
            return "富士康生产的Iphone11";
        }
    }

2.3 建立联系(为委托绑定方法),苹果公司发布生产指令

    class Program
    {
        static void Main(string[] args)
        {
            //苹果公司成立
            var CompanyPhone = new Phone();
            //富士康工厂建立
            var CompanyFoxconn = new Foxconn();
            //苹果公司 和富士康达成合作协议
            CompanyPhone.createIPhone11 = CompanyFoxconn.FoxconnIphon11;
            //苹果公司要求生产
            CompanyPhone.IPhone11Create();
            Console.ReadLine();
        }
    }

2.4 执行结果

2.5 总结:上面的例子主要想要表述委托在实际生活中的运用,整个委托运用过程如下

1.定义委托(特殊类)

public delegate string CreateIPhone11Delegate(string space);

2.实例化委托

public CreateIPhone11Delegate CreateIPhone11 = null;

3.为委托绑定方法

3.1 CreateIPhone11 = fun1;

3.2 CreateIPhone11+=fun2;  委托可以绑定一系列符合要求的方法(相当于IPHONE11可以有不同的代工厂同时生产),在INVOKE时候依次执行

4.取消委托绑定的方法

CreateIPhone11 -= fun1; 取消不合格的代工厂

5.有些地方可以简化2,3步骤,初始化直接绑定

public CreateIPhone11Delegate CreateIPhone11 = fun1;

三、进阶

如上,每次使用委托的时候都要定义一个委托类型,指定要绑定方法的输入输出类型,.netframework2.0 以后出现了泛型,框架就提预定义的委托类型,方便我们直接使用

3.1 Action

看源码

    //
    // 摘要:
    //     封装一个方法,该方法不具有参数且不返回值。
    [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
    public delegate void Action();

其实就是一个委托类型,和我们定义的时候一模一样,无参输入,无参输出。

也可以通过泛型,指定多个(最多16个输入参数),但都无返回值

3.2 Func

看源码:

using System.Runtime.CompilerServices;

namespace System
{
    //
    // 摘要:
    //     封装一个方法,该方法不具有参数,且返回由 TResult 参数指定的类型的值。
    //
    // 类型参数:
    //   TResult:
    //     此委托封装的方法的返回值类型。
    //
    // 返回结果:
    //     此委托封装的方法的返回值。
    [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
    public delegate TResult Func<out TResult>();
}

也是系统定义的委托类型,只不过有一个强行的输出类型

同样,也有泛型的委托,支持16个参数的输入

所以可以简化我们上面的代码无需自己定义单独的委托,使用系统预定义的委托,完整如下:

namespace PhoneCreate
{
    class Program
    {
        static void Main(string[] args)
        {
            //苹果公司成立
            var CompanyPhone = new Phone();
            //富士康工厂建立
            var CompanyFoxconn = new Foxconn();
            //苹果公司要求生产   并将富士康生产方法传入
            CompanyPhone.IPhone11Create(CompanyFoxconn.FoxconnIphon11);
            Console.ReadLine();
        }
    }    

    public class Phone
    {
        /// <summary>
        /// 发布开始生产指定
        /// </summary>
        public void IPhone11Create(Func<string,string> createIPhone11)
        {
            if(createIPhone11!=null)
            {
                Console.WriteLine($"新款IPhone【{createIPhone11.Invoke("6.1寸")}】");
            }
        }
    }
    public class Foxconn
    {
        /// <summary>
        /// 实现IPhone11生产
        /// </summary>
        /// <param name="space"></param>
        /// <returns></returns>
        public string FoxconnIphon11(string space)
        {
            //一系列逻辑
            return $"富士康生产的Iphone11{space}";
        }
    }

四、实际运用

冥冥之中,我们其实已经在使用委托,只是,我们可能不知道而已,下面例子,假设两个员工工资和年薪都不一样,我们要找出所有员工中最高薪资,最高年终奖,最高年收入是多少,需要用List 中Max方法。

4.1 创建员工对象

public class Emp
    {
        //姓名
        public string EmpName { get; set; }
        //月薪
        public int Salary { get; set; }
        //年终奖
        public int Bonus { get; set; }
        public override string ToString()
        {
            return $"{EmpName}:年薪:{Salary},年终奖:{Bonus}";
        }
    }

4.2 创建列表

            List<Emp> emps = new List<Emp>();
            emps.Add(new Emp
            {
                EmpName = "Nemo",
                Salary = 100000,
                Bonus = 20000
            });
            emps.Add(new Emp
            {
                EmpName = "Claire",
                Salary = 120000  ,
                Bonus = 1000
            });

4.3 分别找出符合条件员工

            //年薪最高值
            var maxSalary = emps.Max(con => con.Salary);
            //年终奖最高值
            var maxBonus = emps.Max(con => con.Bonus);
            //年收入最高值
            var maxInput = emps.Max(con => con.Salary + con.Bonus);

            Console.WriteLine($"年薪最高值:{maxSalary.ToString() }");
            Console.WriteLine($"年终奖最高值:{maxBonus.ToString() }");
            Console.WriteLine($"年收入最高值:{maxInput.ToString() }");
            Console.ReadLine();

4.4 输出结果

4.5 max 方法解析,先看源码

Func<TSource,int>就是一个委托,相当于,IEnumberable 通过枚举的方式将List的中每个Emp对象给你,然后你制定一个求最大的值得规则,Max然后按照你给的规则进行给你寻找。

当然上面 con=>con.ss  是匿名方法,顺便说一下,就是有时候我们的方法只需要调用一次,就无需单独写一个方法出来,在使用Linq的时候,非常常见。

五、总结

委托,一句话概括,就是可以将方法当做方法的参数进行传递。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值