委托从字面上理解就是一种中介,委托是一种引用类型,虽然在定义委托时与方法有些相似,但不能将其称为方法。
通常将委托分为命名方法委托、多播委托、匿名委托。
命名方法委托
委托使用: 即定义声明委托、实例化委托以及调用委托。
修饰符 delegate 返回值类型 委托名 ( 参数列表 );
了解一下简单的委托定义与使用:
public class SimpleDelegate
{
/// <summary>
/// 定义委托---代表可以回调返回值为空的无参数方法
/// </summary>
delegate void MyDelegate();
/// <summary>
/// 定义委托---代表可以回调返回值为空的有参数方法
/// </summary>
delegate void MyDelegate1(int a);
/// <summary>
/// 定义委托---代表可以回调返回值为int的有参数方法
/// </summary>
delegate int MyDelegate2(int a, int b);
public static void Test()
{
Console.WriteLine("返回值为空,无参数方法");
}
public static void Test1(int a)
{
Console.WriteLine($"返回值为空,参数为{a}");
}
public static int Test2(int a, int b)
{
int c = a + b;
Console.WriteLine($"返回值为{c},参数1为{a},参数2为{b}");
return c;
}
public static void TestDelegate()
{
//创建实例委托
var proxy = new MyDelegate(Test);
//回调委托方法一
proxy.Invoke();
//回调委托方法二
proxy();
//创建实例委托
var proxy1 = new MyDelegate1(Test1);
proxy1.Invoke(100);
//创建实例委托
var proxy2 = new MyDelegate2(Test2);
proxy2.Invoke(100, 89);
}
}
委托协议
遵循同一个协议
/// <summary>
/// 委托协议
/// </summary>
public interface IRentHouse
{
void RentHouse();
}
/// <summary>
/// 代理的目标对象
/// </summary>
public class Lila : IRentHouse
{
public void RentHouse()
{
Console.WriteLine("Lila需要租房子");
}
}
/// <summary>
/// 房屋中介代理(委托)
/// </summary>
public class HouseMedium : IRentHouse
{
private IRentHouse? target;
private int money;
/// <summary>
/// 在构造代理对象的时候传入目标对象
/// </summary>
/// <param name="house"></param>
public HouseMedium(IRentHouse? house, int mon)
{
target = house;
money = mon;
}
/// <summary>
/// 对原有目标对象中的方法进行增强实现(Aop(面向切面)基础)
/// </summary>
public void RentHouse()
{
//实际调用目标代理对象中的方法
if (money > 500)
{
Console.WriteLine(" 租房加急");
Console.WriteLine(" 筛选房源");
Console.WriteLine(" 匹配条件");
target.RentHouse();//调用目标对象本身的方法
Console.WriteLine("已经找到房子");
}
else
{
Console.WriteLine(" 正常速度找房");
target.RentHouse();
Console.WriteLine("已经找到房子");
}
}
}
public void test()
{
// 1.创建目标对象实例
var Lila = new Lila();
//2.创建房屋中介代理对象
var proxy = new HouseMedium(Lila, 650);
//3.交给代理找房子
proxy.RentHouse();
}
委托指向多个函数
public class Persons
{
public string firstnme { get; set; }
public string secondnme { get; set; }
public Persons(string fb, string sd)
{
this.firstnme = fb;
this.secondnme = sd;
}
public void ShowFirstName(string msg)
{
Console.WriteLine(msg + firstnme);
}
public void ShowSecondName(string msg)
{
Console.WriteLine(msg + secondnme);
}
}
//定义委托
delegate void PersonDelegatecc(string msg);
public static void Testt()
{
Persons persons = new Persons("Lisa", "Bobo");
//实例化委托
PersonDelegatecc personDelegatecc = new PersonDelegatecc(persons.ShowFirstName);
personDelegatecc("第一个名字");
personDelegatecc = persons.ShowSecondName;
personDelegatecc("第二个名字");
}
多播委托
拥有对多个方法引用的委托;多播委托必须仅包含void的方法,否则运行异常
//定义多播委托
delegate void DBDelegatecc(int x, int y);
public class Oper
{
public static void Add(int a, int b)
{
Console.WriteLine("{0}+{1}={2}", a, b, a + b);
}
public static void Sub(int a, int b)
{
Console.WriteLine("{0}-{1}={2}", a, b, a - b);
}
}
public static void DBTest()
{
//绑定方法一
DBDelegatecc dBDelegatecc = new DBDelegatecc(Oper.Add);
//绑定方法二
dBDelegatecc += new DBDelegatecc(Oper.Sub);
//顺序执行12两个方法
dBDelegatecc(10, 3);
//注销方法
dBDelegatecc -= new DBDelegatecc(Oper.Sub);
dBDelegatecc(22, 2);
}
匿名委托
直接在实例化委托时,不另外定义方法,而是在委托内部实现操作。适用于只调用一次委托且代码较少的情况
private delegate string NonDelegate();
/// <summary>
/// 匿名委托方法
/// </summary>
public static void TestNonDelegate()
{
NonDelegate nonDelegate = delegate
{
return "NonDelegate";
};
Console.WriteLine(nonDelegate());
}
public void test()
{
Console.WriteLine("匿名委托函数测试======》");
TestNonDelegate();
}
委托作为参数
public class Mathclass
{
public delegate int MathDelegate(int a, int b);
public static int Multiply(int a, int b)
{
return a * b;
}
public static int Devide(int a, int b)
{
return a / b;
}
public static void Operator(int a, int b, MathDelegate mathDelegate)
{
var result = mathDelegate.Invoke(a, b);
Console.WriteLine("result={0}", result);
}
}
public static void TestDelegateCS()
{
Mathclass.Operator(10, 2, new Mathclass.MathDelegate(Mathclass.Multiply));
Mathclass.Operator(10, 2, new Mathclass.MathDelegate(Mathclass.Devide));
///另一写法:
Mathclass.Operator(10, 2, Mathclass.Multiply);
Mathclass.Operator(10, 2, Mathclass.Devide);
}
.NET内置委托
Action<>委托:以参数形式传递方法,不用显示声明自定义委托;封装的方法必须与此委托定义的方法签名相对应;封装的方法无返回值
Func<>委托:引用了一个带有一个返回值的方法,封装的方法有多个返回值 :
Func<out TResult>
Func<in T,out TResult>
Func<in T1,in T2,...,in T16, out TResult>
Action与Func具体使用方法
/// Action用法
/// </summary>
public class Actionclass
{
public static void Test()
{
Action action = new Action(TestAction);
action();
Action<string> action1 = new Action<string>(TestAction1);
action1("vs");
Action<string,int,bool> action2 = new Action<string, int, bool>(TestAction2);
action2("vs",88,false);
}
public static void TestAction()
{
Console.WriteLine("Action无参无返回值");
}
public static void TestAction1(string a)
{
Console.WriteLine("Action有参数值无返回值");
}
public static void TestAction2(string a ,int b,bool c)
{
Console.WriteLine("Action多个参数值无返回值");
}
}
/// <summary>
/// Func用法
/// </summary>
public class Funcclass
{
public static void Test()
{
Func<int> funcion = new Func<int>(TestFunc);
var a1= funcion();
Console.WriteLine("Func无参int返回值{0}",a1);
Func<string,string> funcion1 = new Func<string,string>(TestFunc1);
var a2= funcion1("ngfns");
Console.WriteLine("Func有参数值string返回值{0}", a2);
Func<string, int, bool,bool> action2 = new Func<string, int, bool,bool>(TestFunc2);
var a3= action2("vs", 88, false);
Console.WriteLine("Func多个参数值bool返回值{0}", a3);
}
public static int TestFunc()
{
Console.WriteLine("Func无参int返回值");
return 0;
}
public static string TestFunc1(string a)
{
Console.WriteLine("Func有参数值string返回值");
return a;
}
public static bool TestFunc2(string a, int b, bool c)
{
Console.WriteLine("Func多个参数值bool返回值");
return c;
}
}
public void test()
{
Console.WriteLine(".net委托测试======》");
Actionclass.Test();
Funcclass.Test();
}
Action与Func匿名委托
/// <summary>
/// Action与func匿名委托
/// </summary>
/// <param name="args"></param>
public static void NMDelegate()
{
Action<int> action = delegate (int i) { Console.WriteLine("参i数值为{0}", i); };
action(500);
Action<string>action1=(string s) => { Console.WriteLine("参i数值为{0}", s); };
action1("bsbn");
Func<int, string> func = delegate (int a) { return a.ToString(); };
var s= func(999);
Console.WriteLine("返回值为{0}", s);
Func<string, string> func1 =(string a)=> { return a; };
var s1= func1("fsnsns");
Console.WriteLine("返回值为{0}", s1);
}