学习C#语言到了委托事件这块就感觉比较抽象,因而做笔记方便理解。
委托:函数的包装,让函数可以作为参数进行使用(C++里的函数指针)。
委托一个重要的作用是实现方法回调,使得我们在添加方法时更利于拓展,而不用频繁修改逻辑判断部分
namespace 委托1{
//定义委托 - 访问修饰符 delegate 返回值类型 委托名(参数列表);
public delegate void Something(string name);
public class Student{
//可以像普通类型一样当做方法参数传递
public void Do(Something something){
//可以像普通方法一样调用
//真正调用了方法A - 方法回调
something(name);
}
public Student(string name){
this.name = name;
}
private string name;
}
public class Teacher{
public void Hungry(){
Student s = new Student("老王");
//创建委托变量
Something a = new Something(A);
Something b = new Something(B);
Something c = a + b;
委托对象可以使用+ - 来绑定、解除绑定其他委托变量
c = c - a;
s.Do(c);
}
public void A(sting name){
Console.WriteLine("Hello,"+name);
}
public void B(sting name){
Console.WriteLine(name+"为老师买早饭");
}
}
class MainClass{
public static void Main(string[] args){
Teacher t = new Teacher();
t.Hungry();
}
}
}
上述例子,1、将委托作为参数封装在学生的Do(Something something)函数中,如此,2、老师若要学生完成指定的A或B方法,便可以将老师的函数直接传递过去A(string name)、B(string name)。
概括下即:老师饿了(Hungry),在Hungry函数中通过创建的委托变量,修改增添AB方法,并传递到学生已封装好的带有委托传递的Do函数里,最后调用老师的AB方法(方法回调),学生就为老师买好了早饭。
namespace 委托2{
class Person{
public delegate int MyDelegate(int num1,int num2);
public int Compare(int n1,int n2){
return n1 > n2 ? n1 : n2;
}
public void func(MyDelegate dd,int nn1,int nn2){
int result = dd(nn1,nn2);
Console.WriteLine(result);
}
}
class MainClass{
public static void Main (string[] args){
Person p = new Person();
p.func(p.Compare,10,20);
}
}
上述案例更简洁,我们在Main类中负责比较两个人的年龄,那么首先调用person类里的func函数,由func再负责传递compare函数,我们也可以新增其他函数传递,用来比较两个人的其他关系。
我们再来介绍unity文档里已经帮我们定义好的委托Action和Func:
Action委托无返回值,但可自定义多个参数,还可以通过泛型委托在后面绑定传递方法时指定参数类型。
namespace Action委托{
class Program{
static void PrintString(){
Console.WriteLine("hello world");
}
static void Print(int i,string o){
Console.WriteLine(i + o);
}
static void Main(string[] args){
Action a = PrintString;//系统内置的委托类型,指向没有返回值没有参数的方法
Action<int,string> b = Print;//定义了一个委托类型,指向没有返回值有参数的方法
a();
b(3,"andy");
Console.ReadyKey();
}
}
}
Func委托必须有返回值,同样可以自定义多个参数,也可以通过泛型委托指定参数类型。划重点:Func<T1,T2...N1>,T的个数0~16,N1有且只有一个作为返回值类型。
namespace Func委托{
class Program{
static int Test1(){
return 1;
}
static int Test2(string str){
Console.WriteLine(str);
return 100;
}
static void Main(string[] args){
Func<int> a = Test1;
Func<string,int> b = test2;
Console.WriteLine(a());
Console.ReadKey();
}
}
}
以上就是最近学习委托的一点心得,实际运用仍需更多案例。
补充一点:多播委托。
其实第一个案例定义委托声明变量时,合并删除方法,即多播委托的特性。
多播委托包含了一个逐个调用方法的集合,我们可以就多播委托的特性来遍历集合,单独调用或完成其他你想实现的效果。
namespace 多播委托{
class Program{
static void Test1(){
Console.WriteLine("test1");
}
static void Test2(){
Console.WriteLine("test2");
}
static void Main(string[] args){
Action a = Test1;
a += Test2;
Delegate[] delegates = a.GetInvocationList();//该方法返回一个委托类型的集合
foreach(Delegate de in delegates){
De.DynamicInvoke();//可以把方法的参数传进去
}
Console.ReadKey();
}
}
}
多播委托处理返回值:只将最后一个委托方法的结果输出来