求知若饥,虚心若愚
声明委托类型
委托是引用类型,但不需要用new实例化,c#2.0起会自动将方法组转换为委托类型,所有委托不可变
常用委托
- System.Func,接收参数并返回,最多十六个参数
- System.Action,接收参数无返回,最多十六个参数
- System.predicate,接收一个参数并返回bool,谓词
Lambda表达式
- 语句Lambda,由形参列表,Lambda操作符=>,和代码块组成。()=>{},注意一般语句限制两三个语句之内。
- 表达式Lambda,代码块变成返回语句,可以将=>理解成满足…条件,()=>xx
- 注意事项:Lambda表达式本身没有类型,禁用各种var,is,as操作符。不允许内部使用跳转语句。
匿名方法
- c#2.0时期还没有Lambda,实际是用委托来实现。
- 尽量用Lambda语句。
- 在CLR看来,最终都会转换成特殊的隐藏类、字段或方法。
- 如果捕捉了外部变量,那么外部变量的生命周期还需要考虑委托的生命周期,总之取最长那个(可能更长)。被捕捉的变量将会变成生成的匿名类的成员存在,后续使用都使用实例的成员,该类被称为闭包。
- 匿名函数捕捉外部变量时,要小心循环变量,如果不显式在内部定义局部变量,那么可能会将捕捉变量认为成旧的并不断覆盖。c#5.0foreach语句已经修正,允许每次循环将捕捉变量视作新变量,但使用for语句还需要小心。
1 | BubbleSort(items, |
委托没有结构相等性
即便委托签名一致,也不能将一个委托类型的对象引用转换成一个不相关的委托类型。但可以通过f = c.Invoke;获取其内部函数。
c#4.0起增加了可变性的支持,可以通过逆变将有父子关系的委托转换,详见上一节。
1 | // Contravariance |
表达式树
用于与服务器交互