c#之委托总结
2014-02-27 14:48
134 查看
1、委托的声明和编译原理
声明委托:
通过反编译之后可得下面代码
委托是由三部分组成:1、Target(指向方法的实例(就是方法的类),对应上面的 o)2、Method(指向方法的 类型) 3、委托链(InvorkList):多播委托。委托时一个object数组,每增加一个方法,实际CLR会将其封装成一个委托,将其添加到object[]中。然后调用的时候,通过“类型指针”指向对应的委托的地址,然后指针在向下指向下一个委托,知道数组中所有委托都执行完毕。)
[b]2、委托的使用[/b]
匿名的方式给委托赋值:
3、委托的作用:
占位:向一个方法函数中传递一个委托类型的变量,因为方法函数中不知道要执行什么方法,但是知道方法的类型,所以用一个委托作为形参传递进去,然后实参由使用的用户自行定义,只要符合委托类型就可以了。(实际上:就是传递进去一个委托类型的形参,就可以传递不同的(只要符合委托类型)的实参方法。)
演示:实现不同排序方法
首先定义委托:
定义排序函数:
第一种排序:
第二种排序
[b]4、多播委托[/b]
委托含有一个“委托链”,是一个object[]类型的数组,执行的之后,委托的“类型指针”(方法指针)会执行下一个委托,一次类推,执行完成所有的委托
注意:多播委托的委托最好不要要返回值。如果有返回值,那么执行多播委托的时候,多播委托的返回值是最后一个委托方法执行的返回值。
[b] 5、泛型委托[/b]
泛型:就是约束:约束的是传入的参数的个数类型和返回值的类型。
分为两种:有返回值泛型委托:Func 和 无返回的泛型委托:Action
有返回值的泛型委托
无返回值的泛型委托:
[b]6、异步委托[/b]
什么是异步委托:当当前主线程执行的时候,定义一个新的 线程,执行相应的代码,但是不影响主线程。
第一种:不使用回调函数
第二种:使用回调函数
首先为回调函数定义方法:
执行异步委托:
声明委托:
delegate void Translate(string str);
通过反编译之后可得下面代码
private sealed class Translate:System.MulticastDelegate//就是一个多播委托 { public Translate(object o, Method m) { }//(实现委托方法),隐性传进来的 o 就是 当前类的 this对象,第二个参数是传进来的事件 public void Invoke(string str) { }//实现 委托的方法(向委托事件里面 传递参数) // 所以可以通过 new 调用 委托业务函数 ,可以 调用 Invoke()方法来实现 }
委托是由三部分组成:1、Target(指向方法的实例(就是方法的类),对应上面的 o)2、Method(指向方法的 类型) 3、委托链(InvorkList):多播委托。委托时一个object数组,每增加一个方法,实际CLR会将其封装成一个委托,将其添加到object[]中。然后调用的时候,通过“类型指针”指向对应的委托的地址,然后指针在向下指向下一个委托,知道数组中所有委托都执行完毕。)
[b]2、委托的使用[/b]
//1.向方法 里面添加 委托 tran = new Translate(TranSlateCN);//创建委托 //tran = TranSlateCN;//第二种创建委托的方法(效果同上) tran.Invoke("北疆");//实现委托的方法 tran("北疆");//调用 委托事件(实现的 就是上面的 方法)
匿名的方式给委托赋值:
AddDel adddemo2 = delegate(int c, int b) { return c + b; };
3、委托的作用:
占位:向一个方法函数中传递一个委托类型的变量,因为方法函数中不知道要执行什么方法,但是知道方法的类型,所以用一个委托作为形参传递进去,然后实参由使用的用户自行定义,只要符合委托类型就可以了。(实际上:就是传递进去一个委托类型的形参,就可以传递不同的(只要符合委托类型)的实参方法。)
演示:实现不同排序方法
首先定义委托:
public delegate int GetMaxDel(object o1, object o2);
定义排序函数:
public object GetMax(object[] objs, GetMaxDel maxdel) { object maxobj = objs[0]; foreach (var item in objs) { if (maxdel(item, maxobj) > 0) { maxobj = item; } } return maxobj; }
第一种排序:
GetMaxDel maxdel1 = delegate(object o1, object o2) { int num1 = Convert.ToInt32(o1); int num2 = Convert.ToInt32(o2); return num1 - num2; }; object[] objs = { 4, 1, 7, 3, 2 }; object result = d.GetMax(objs, maxdel1); Console.WriteLine(result.ToString());
第二种排序
GetMaxDel maxdel2 = delegate(object o1, object o2) { Person p1 = o1 as Person; //Person是实现定义的类 Person p2 = o2 as Person; if (p1.Age > p2.Age) return 1; else return -1; };
[b]4、多播委托[/b]
委托含有一个“委托链”,是一个object[]类型的数组,执行的之后,委托的“类型指针”(方法指针)会执行下一个委托,一次类推,执行完成所有的委托
SayHi sayhi = new SayHi(d.SayHiInChinese); // sayhi = (SayHi) Delegate.Combine(sayhi, new SayHi(d.SayHiInEnglish)); 反编译之后:所以执行的还是两个委托 相加 sayhi += d.SayHiInEnglish; sayhi += d.SayHiInFresh; sayhi("大家好"); sayhi -= d.SayHiInFresh; //调用的是Delegate.Remove(new Delegate(d.SayHiInFresh)); //下面是 将方法 封装成 委托 在进行相加(和上面直接加 方法 是一样的(编译成相同的代码)) SayHi sayhello = new SayHi(d.SayHiInFresh); //两个委托相加 sayhi += sayhello;
注意:多播委托的委托最好不要要返回值。如果有返回值,那么执行多播委托的时候,多播委托的返回值是最后一个委托方法执行的返回值。
[b] 5、泛型委托[/b]
泛型:就是约束:约束的是传入的参数的个数类型和返回值的类型。
分为两种:有返回值泛型委托:Func 和 无返回的泛型委托:Action
有返回值的泛型委托
List<int> listInt = new List<int>() { 1, 2, 3, 4, 5 }; //有返回值的 泛型委托。(使用的最多) //前面可以传递 最多 (出入参数)十六参数 最后一个传出参数(out 类型)的是bool类型的(判断是否满足要求) Func<int, bool> funcdel = a => a > 2; //函数原型:public delegate TResult Func<in T, out TResult>(T arg); 实质:也是委托,只不过对 传入参数 和返回值 做了约束 //List 的where方法(用户筛选 List里面 的 满足 泛型 委托 函数的 ) var result = listInt.Where(funcdel); foreach (var i in result) { Console.WriteLine(i); }
无返回值的泛型委托:
//无返回值的 泛型委托 Action,,很少使用 //委托的 函数原型:public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2); Action<int, int> act = (a, b) => { Console.WriteLine(a+"+"+b+"+"+(a+b)); }; act.Invoke(2,3);
[b]6、异步委托[/b]
什么是异步委托:当当前主线程执行的时候,定义一个新的 线程,执行相应的代码,但是不影响主线程。
第一种:不使用回调函数
//第一种(EndInvoke会阻塞当前线程(主线程)) //异步委托:就是 当主线程 执行的时候, 定义 一个新的线程执行 代码,不影响 主线程的 运行 IAsyncResult delResult = newdel.BeginInvoke(3, 4, null, null);//返回值为 异步委托的结果 while (!delResult.IsCompleted) { //当 异步委托 没有执行完成的 时候 主线程 可以继续执行 自己的代码 } //执行 委托的 EndInvoke 方法 之后返回值就是 委托传进来的 参数方法的 返回值 int addResult = newdel.EndInvoke(delResult);//阻塞当前线程的 执行(直到 异步委托执行完成之后) Console.WriteLine("线程执行完成之后 的结果" + addResult);
第二种:使用回调函数
首先为回调函数定义方法:
//为回调函数 定义 一个方法(根据委托类型 来定义方法 (void 还有参数为 接口)) public static void ForSayCallBack(IAsyncResult iasyResult) { //将接口类型 转换成 实例类型(只要是继承与 此接口的 类 都可以将 接口参数 转换成 实例类型)(*面向接口编程*) AsyncResult asyResult = iasyResult as AsyncResult; //AsyncDelegate:获取 对应的 委托对象 (并将 获得的委托对象 转换成 自己定义的 委托对象) myNewdel mydel= asyResult.AsyncDelegate as myNewdel; //获得了自己的 委托对象 就可以调用 EndInvoke方法了 int result= mydel.EndInvoke(iasyResult); Console.WriteLine("次异步委托执行了,执行的返回结果为{0},线程Id为:{1}",result, Thread.CurrentThread.ManagedThreadId); //取到 为回调函数 传递的值(**) int state =(int) iasyResult.AsyncState; }
执行异步委托:
newdel.BeginInvoke(2, 3, new AsyncCallback(ForSayCallBack), 3);//最后一个参数(object类型:可以传递多个值(比如传递一个List类型)) :为回调函数传值 //(**)BeginInvoke内部实现:第一步:从线程池 里面 拿过来一个 新的线程 第二步:用此线程 执行 当前委托(调用异步委托的委托)要执行的方法 第三步:执行 回调函数 Console.WriteLine("主线程执行完毕!");
相关文章推荐
- c#中委托的概念一个总结demo
- 【C#复习总结】细说泛型委托
- C#的基础琐碎总结-----委托
- C#之入门总结_线程,委托,事件的关系_20
- C# 委托总结
- c#委托知识总结
- C#中的委托和事件--7.总结
- 一起谈.NET技术,C# 委托知识总结
- Unity&C#的委托事件总结
- C#中的委托和事件 (7)---总结
- C# 委托知识总结
- C#中委托的基本用法总结
- C# 委托应用总结
- C# 委托 事件 观察者模式 总结
- C#委托知识总结
- C# 委托应用总结
- 一个平凡菜鸟的C#琐碎总结 ---- -委托
- 总结:CLR Via C#(第15章):委托
- C# 委托应用总结(委托,Delegate,Action,Func,predicate)
- C#中的多播委托笔记总结(转)