C#学习笔记:泛型委托Action<T>和Fun<TResult>
http://www.cnblogs.com/Joetao/articles/2094271.html
http://blog.csdn.net/ruijc/article/details/6904667
转自:http://www.cnblogs.com/hyddd/archive/2009/07/26/1531538.html#3183896
http://kb.cnblogs.com/page/50132/
http://www.csframework.com/archive/2/arc-2-20110617-1633.htm
http://blog.sina.com.cn/s/blog_5f30147a010111y1.html
http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html
http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx
http://blog.csdn.net/huifeidexin_1/article/details/7567731
http://bbs.9ria.com/thread-205585-1-1.html
C#综合揭秘——深入分析委托与事件
http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html
引言
本篇文章将为你介绍一下 Delegate 的使用方式,逐渐揭开 C# 当中事件(Event)的由来,它能使处理委托类型的过程变得更加简单。
还将为您解释委托的协变与逆变,以及如何使用 Delegate 使 Observer(观察者)模式的使用变得更加简单。
在事件的介绍上,会讲述事件的使用方式,并以ASP.NET的用户控件为例子,介绍一下自定义事件的使用。
最后一节,将介绍Predicate<T>、Action<T>、Func<T,TResult>多种泛型委托的使用和Lambda的发展过程与其使用方式。
因为时间仓促,文中有错误的地方敬请点评。
目录
C# 委托及各种写法
- 委托是嘛?
委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)。通俗的说,委托是一个可以引用方法的对象,当创建一个委托,也就创建一个引用方法的对象,进而就可以调用那个方法,即委托可以调用它所指的方法。
- 如何使用委托?
1、定义委托类型
[访问修饰符]delegate 返回类型 委托名(形参);
2、声明委托对象
委托名 委托实例名;
3、创建委托对象(确定与哪些方法进行绑定)
委托实例名=new 委托名(某个类的方法)
4、使用委托调用方法
委托实例名(实参)
- 委托注意事项:
1、委托和方法必须具有相同的参数。
2、委托可以调用多个方法,即一个委托对象可以维护一个可调用方法的列表而不是单独的一个方法,称为多路广播(多播)。
3、使用+=和-=运算实现方法的增加和减少
- 示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Delegate;
namespace Delegate
{
public delegate int Call(int num1, int num2);//第一步:定义委托类型
class SimpleMath
{
// 乘法方法
public int Multiply(int num1, int num2)
{
return num1 * num2;
}
// 除法方法
public int Divide(int num1, int num2)
{
return num1 / num2;
}
}
}
class Test
{
static void Main(string[] args)
{
Call objCall;//第二步:声明委托对象
// Math 类的对象
SimpleMath objMath = new SimpleMath();
// 第三步:创建委托对象,将方法与委托关联起来
objCall = new Call(objMath.Multiply);
Call objCall1 = new Call(objMath.Divide);
objCall += objCall1;//向委托增加一个方法
//objCall -= objCall1;//向委托减去一个方法
// 调用委托实例,先执行objMath.Multiply,然后执行objMath.Divide
int result = objCall(5, 3);
System.Console.WriteLine("结果为 {0}", result);
Console.ReadKey();
}
}
写法:
1、委托 委托名=new 委托(会调用的方法名); 委托名(参数);
2、委托 委托名 =会调用的方法名; 委托名(参数);
3、匿名方法
委托 委托名=delegate(参数){会调用的方法体};委托名(参数);
4、拉姆达表达式
委托 委托名=((参数1,。。参数n)=>{会调用的方法体});委托名(参数);
5、用Action<T>和Func<T>,第一个无返回值
Func<参数1, 参数2, 返回值> 委托名= ((参数1,参数2) => {带返回值的方法体 });返回值=委托名(参数1,参数2);
贴代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using @ delegate ; namespace @ delegate { public delegate int Call( int num1, int num2); class SimpleMath { // 乘法方法 public static int Multiply( int num1, int num2) { return num1 * num2; } // 除法方法 public int Divide( int num1, int num2) { return num1 / num2; } } class Test { static void Main( string [] args) { //--------------------第一种写法------------------------// //Call objCall = new Call(SimpleMath.Multiply); //Call objCall1 = new Call(new SimpleMath().Divide); //--------------------第二种写法------------------------// //Call objCall = SimpleMath.Multiply; //Call objCall1 = new SimpleMath().Divide; //--------------------第三种写法------------------------// //Call objCall = delegate(int a, int b) //{ // return a * b; //}; //Call objCall1 = delegate(int a, int b) //{ // return a / b; //}; //--------------------第四种写法------------------------// //Call objCall =((int a,int b)=> { return a*b;}); //Call objCall1 = ((int a, int b) => { return a / b; }); //--------------------第五种写法------------------------// Func< int , int , int > objCall = ((a, b) => { return a * b; }); Func< int , int , int > objCall1 = ((a, b) => { return a / b; }); Action< int , int > ob = ((a, b) => { Console.WriteLine(a * b); }); ob(5, 3); //----------------------------------------------------// int result = objCall(5, 3); int result1 = objCall1(5, 3); System.Console.WriteLine( "结果1为 {0},结果2为{1}" , result,result1); Console.ReadKey(); } } } |
某人有三子,让他们各自带一样东西出门,并带回一头猎物。
可以理解为一种父亲对儿子的委托:
猎物 办法(工具 某工具)
三个人执行委托的方法各不相同
兔子 打猎(工具 弓)
野鸡 买(工具 钱)
狼 诱捕(工具 陷阱)
委托是一个类型,用来指称所有形式相同的方法(返回值类型相同而且参数也相同)。
public delegate double Handler(double[] ds);
public double Sum(double[] ds) {//在方法中执行操作。}
public double Average(double[] ds) {//在方法中执行操作。}
委托的实例化
用new关键字(将方法名作为参数)生成一个委托对象,建立委托与方法的关联。
例:Handler handler = new Handler(Sum);使用委托可以像使用变量一样使用委托的实例。使用委托时,需要给委托按要求传递参数。
使用委托,则委托所关联的方法被调用。
例:double[] weights={1.0,2.0,3.0,4.0};
double result=handler(weights);
一个委托可以通过+运算委托关联多个方法,叫多路广播委托(对应于单路广播委托)。
如果此时使用委托,则所有的关联方法都被调用。
例:Handler handler = new Handler(Sum);
handler += new Handler(Average);
这个委托(第三方)就会去调用方法去帮你实现
委托的好处:
1.相当于用方法作为另一方法参数(类似于C的函数指针)
2.在两个不能直接调用的方法中作为桥梁,如:在多线程中的跨线程的方法调用就得用委托