一、基本概念
有过买二手房交易的朋友都有感触,办理过户等等一系列手续都是相当麻烦的,这个时候,房产中介出现了,我们只需要将必备资料交个中介,他们就会帮忙办理的妥妥的,我们并不需要关系整个办理过程,这个过程就是委托,委托房产中介办理相关手续。再入,我们用的苹果手机,也并不是苹果公司直接生产,也是委托代工厂进行生产,下面就通过苹果手机的代理生产过程解析委托。
二、苹果手机代工过程
2.1 苹果公司定义好本次手机的生产规格(定义委托)传入生产规格,返回手机
public class Phone
{
///
/// 定义委托,传入生产规格,返回一个符合规格的手机
///
///
///
public delegate string CreateIPhone11(string space);
//等待代工厂加入
public CreateIPhone11 createIPhone11 = null;
///
/// 发布开始生产指定
///
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();
}
也是系统定义的委托类型,只不过有一个强行的输出类型
同样,也有泛型的委托,支持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
{
///
/// 发布开始生产指定
///
public void IPhone11Create(Func createIPhone11)
{
if(createIPhone11!=null)
{
Console.WriteLine($"新款IPhone【{createIPhone11.Invoke("6.1寸")}】");
}
}
}
public class Foxconn
{
///
/// 实现IPhone11生产
///
///
///
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 emps = new List();
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
当然上面 con=>con.ss 是匿名方法,顺便说一下,就是有时候我们的方法只需要调用一次,就无需单独写一个方法出来,在使用Linq的时候,非常常见。
五、总结
委托,一句话概括,就是可以将方法当做方法的参数进行传递。