委托学习(一)
之前有学过,但也是一知半解,现在有空重新去查找一些资料学习了一下,虽然也是从别人那儿学来的,但是也正努力的根据自己的理解去写例子。
- 通过实例了解委托的概念
- 委托的回调
- 委托的深入(委托链 - 合并删除委托)
- 委托的源码解析
- 泛型委托
- 委托的进步(语法糖,协变和逆变,匿名,闭包)
- 委托链、泛型委托源码解析
- 委托和反射
- 异步委托
1.通过实例了解委托的概念
什么是委托?:委托是一种类型,属于引用类型,委托的关键字:delegate。委托与类的定义是一样的,能定义类的地方也能定义委托。
如何创建一个无参和有参的委托?
案例1:委托的基本组成
class Program { delegate void myDelegate_No(); delegate void myDelegate_Have(string Name); static void Main(string[] args) { myDelegate_No myDelegate_No = new myDelegate_No(MyMethod); myDelegate_No(); myDelegate_Have myDelegate_Have = new myDelegate_Have(MyMethod); myDelegate_Have("Have"); Console.Read(); } public static void MyMethod() { Console.WriteLine("创建一个无参的方法"); } public static void MyMethod(string Name) { Console.WriteLine("创建了一个有参的方法,传入一个名字为:"+Name); } }
2.委托回调静态方法和实例方法
回调函数怎么理解?或者说回调函数为什么被成为回调函数?
比如调用了一个函数,那么就叫做调用,但是如果在调用一个函数A的时候还需要把这个函数A提交给该函数B,让函数B调用函数A,那么提供的函数A就成为回调函数 (callBack)
理解上述描述之后再来理解“委托回调”也就不难理解了。
案例2:委托回调
class Program { delegate void MyDelegate(); static void Main(string[] args) { //委托回调静态方法 MyDelegate myDelegate = new MyDelegate(StudyDelegateInstance.getFirstDelegateCallBack); myDelegate.Invoke(); //委托回调实例方法 StudyDelegate studyDelegate = new StudyDelegate(); MyDelegate myDelegate_Instance = new MyDelegate(studyDelegate.getFirstDelegateCallBack); myDelegate_Instance.Invoke(); } } public class StudyDelegate { public void getFirstDelegateCallBack() { Console.WriteLine("这是写的第一个回调委托的实例方法"); } } public class StudyDelegateInstance { public static void getFirstDelegateCallBack() { Console.WriteLine("这是写的第一个回调委托的静态方法"); } }
3.委托的合并与删除
学习这个是为了学习【委托链】,这个会在后文进行补充和学习
案例3:委托的合并和删除
class Program { delegate void MyDelegate(); static void Main(string[] args) { MyDelegate myDelegate = new MyDelegate(StudyDelegateInstance.getFirstDelegateCallBack); StudyDelegate studyDelegate = new StudyDelegate(); MyDelegate myDelegate_Instance = new MyDelegate(studyDelegate.getFirstDelegateCallBack); //委托的合并 var delegate_Combine= (MyDelegate)Delegate.Combine(myDelegate,myDelegate_Instance); //相当于:var delegate_Combine = myDelegate += myDelegate_Instance; delegate_Combine.Invoke(); //委托的与删除 var delegate_Rmove = (MyDelegate)Delegate.Remove(delegate_Combine,myDelegate); //相当于 var delegate_Rmove = delegate_Combine - myDelegate; delegate_Rmove.Invoke(); Console.ReadLine(); } } public class StudyDelegate { public void getFirstDelegateCallBack() { Console.WriteLine("这是写的第一个回调委托的实例方法"); } } public class StudyDelegateInstance { public static void getFirstDelegateCallBack() { Console.WriteLine("这是写的第一个回调委托的静态方法"); } }
Remove(source,value)新的委托,其调用列表的构成采用的调用列表 source 和删除的调用列表的最后一个匹配项 value, ,如果的调用列表 value 的调用列表中找到 source。 返回 source 如果 value 是 null 或者,如果的调用列表 value 的调用列表中找不到 source。 如果返回 null 引用的调用列表 value 的调用列表等于 source 或者,如果 source 为空引用。
4.泛型委托
c#变成指南给出的解释和案例(属于自定义的泛型委托)。泛型的好处是减少复杂性,提高可重用性,参考文章来源:http://www.cnblogs.com/DeepLearing/p/4554867.html#3211258
引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型,就像实例化泛型类或调用泛型方法一样 public delegate void Del<T>(T item); public static void Notify(int i) { } Del<int> m1 = new Del<int>(Notify);
其实在c#2.0版之后提供了两种泛型委托:Action和Func.
Action:.NET FreamWork提供了17个Action委托,从无参数到16个参数,如果超过16个就需要自己定义了,同时Action并不带有返回值。
案例4:
class Program { static void Main(string[] args) { Action<string, int, string> ActionStudent = new Action<string, int, string>(Student); ActionStudent.Invoke("c#",2,"c#学习书本"); Console.ReadKey(); } public static void Student(string Name,int Age,string Address) { Console.WriteLine("名字:"+Name+",年龄:"+Age+",地址:"+Address); } }
Func:一样提供了从无参到16个参数外加一个返回值。
案例5:
static void Main(string[] args) { Func<string,int, string,string> FuncStudent = new Func<string, int, string,string>(Student); string studentFunc = FuncStudent.Invoke("c#",2,"c#学习书本"); Console.WriteLine(studentFunc); Console.ReadKey(); } public static string Student(string Name,int Age,string Address) { string studentInfo = "名字:" + Name + ",年龄:" + Age + ",地址:" + Address; return studentInfo; }
参考网址: http://www.cnblogs.com/DeepLearing/p/4594518.html