委托、事件、匿名方法、Lambda

一、委托(delegate)                                                                                     

定义:public delegate  void/类型  DefinedDelegate(参数1,参数2...)

委托是类型安全的. 委托实例:DefinedDelegate  deleObj=new DefinedDelegate( fun ) //向委托构造函数传入方法名称

fun定义:  public void/类型 fun(参数1,参数2...)

1)定义的委托返回类型与指向的方法返回类型一致; 2)委托的参数类型及个数与指向的方法参数类型及个数一致

tip:给定委托的实例可以引用任何类型的任何对象上的实例方法或静态方法,只要方法的签名匹配于委托的签名即可

通过委托实例调用方法:deleObj(参数1,参数2...)

1、委托支持多路广播:一个委托变量可以传入多个委托实例(包含方法的) +=

注:多播委托调用时,如果有一个方法体执行异常,委托迭代会停止,后面的方法体将不会执行。

可按以下方式处理:GetInvocationList()返回Delegate对象数组

2、从委托调用列表移除成员: -+

3、方法组转换语法:允许直接将委托调用的方法赋给委托变量(替代等价=通过委托对象传入方法) deleObj=fun() ; deleObj +=fun2(); deleObj -=fun2();

4、委托协变:定义的委托类型返回自定义类型。 

public delegate  自定义类型  DefinedDelegate(参数1,参数2...);
DefinedDelegate deleObj = fun; //此处fun()返回自定义类型
自定义类型  自*类实例 = (自定义类型)deleObj(参数1,参数2...);

5、泛型委托:定义类型参数来表示传入委托目标的实参。

     public delegate void  DefinedDelegate<T> (T arg); 

二、事件(event)                                                                                     

简化自定义方法构建委托调用列表(增、删),自动提供注册和注销方法

public delegate void DefinedDelegate(string msg); 
public event DefinedDelegate eventObj;

1、事件注册语法: eventObj = new DefinedDelegate(fun);

2、方法组转换:eventObj = fun ;

三、匿名方法                                                                                              

省去定义传入委托的方法. 用大括号包起,并以分号结束。

eventObj = delegate
{
      //方法体内逻辑
};

eventObj1 = delegate (object sender,EventArgs e)
{
      //方法体内逻辑
}

1、访问本地变量:匿名方法能够使用定义它的()本地变量,称这些变量为匿名方法的外部变量

    1)匿名方法不能访问定义方法中的ref或out参数

    2)匿名方法中的本地变量不能与外部方法中的本地变量重名

    3)匿名方法可以访问外部类作用域中的实例变量(或静态变量)

四、Lambda表达式                                                                                          

用于简化匿名方法写法。

简化一:

List<int> list = new List<int>();
list.AddRange(new int [] {20,1,32,23});
List<int> evenNum=list.FindAll(
delegate(int i) {return (i%2)==0;}
);

简化二:

List<int> list = new List<int>();
list.AddRange(new int [] {20,1,32,23});
List<int> evenNum=list.FindAll(i=> (i%2)==0);

简化二(补充):

//...1
List<int> evenNum=list.FindAll( i=> (i%2)==0);

//...2 显示定义表达式每个参数类型
List<int> evenNum=list.FindAll( (int i )=> (i%2)==0);

//...3 (i)
List<int> evenNum=list.FindAll( ( i )=> (i%2)==0);

1、使用多个语句处理参数

//...
List<int> evenNum=list.FindAll( i=>
{
      //...多行语句
     //...
});

2、多个(零个)参数的Lambda表达式

Lambda提供一种简明的方式来定义匿名方法。

(msg,result)=>{ // ... };
(string msg, int result)=>{ // ... };

末尾一个实例(大括号扩起的一段C#语句,需要有返回值):

Datas = nodes.ToList().Select(s =>
{
   var temp= s.MapTo<ScriptNodeOutput>();
   temp.DbServerName = s.DbServer.ByName;
   temp.ScriptNodeTypeName = s.ScriptNodeType.Name;
   return temp;
} ).ToList(),
原文地址:https://www.cnblogs.com/senyier/p/6608028.html