1、委托:委托本质上就是函数指针,但由于指针过于灵活,因此在很多语言中都采用了更加安全的替代类型,比如Delphi的对象方法和C#的委托.委托使得方法可以做为参数进行传递,极大的方便了程序的处理(事件本质上就是委托,是委托的一种典型应用)。使用委托的最大好处一是可以实现算法上的分离,二是可以实现一定程度上的动态联编(即面向对象中的所谓多态),对于算法上的分离,在面向对象的模式设计中,策略模式是比较典型的,其实我们使用委托照样可以在一定程度上模仿其功能,实际上使用策略模式在很多时候还不如委托来得简单有效,而且在性能上也比委托差些。由于委托本身也是一种规范和标准,因此在这种层面上和抽象类,接口一样具有多态性。当然,委托的这种多态性也必须遵循编程语言的继承规范:子类实例可以赋给父类变量,反之则不允许。根据这种规范,站在委托的角度,委托具有返回值协变,参数抗变的特性。即实际委托调用的返回值只能是委托定义的返回值类型的子类,实际调用方法的参数必须是委托定义中的参数的父类。
如:public delegateA Compare(Type1 v);
实际调用的方法:public B CompareInstance(Type2 v).根据继承规范,Type2必须是Type1的父类,而B必须是A的子类.
2、匿名方法:在给委托变量实例化的时候,一般是提供一个有名的方法,如:Compare _compare=CompareInstance;但现在C#提供了一种匿名方法,匿名方法是一个代码块,本质上与命名方法没有什区别,但与命名方法相比,提供了如下两个便利:1是书写上,使得委托变量可以与实例化方法在一起,这样有利于理解;2是匿名方法可以访问匿名方法代码块以外的变量,这点上相对于命名方法要灵活很多,这是优点,也是缺点,缺点是其破坏了代码的封装性,当然,你把匿名方法与其所在的代码模块看作是一个整体(如果从逻辑上来讲也确实是个整体),那么这个缺点就无所谓了。下面是简单的例子:
int theTest=0;
Compare _compare = delegate(int v){
theTest ++;
}
_compare(2);//调用.
匿名方法使用上的限制主要是程序控制方面的,比如不能跳转到匿名方法块外部,也不能从外部跳转到匿名方法块内部等。由于这种匿名代码块并不能复用,因此我觉得匿名方法的实际应用价值并不大,何况还可以用λ表达式替代。
3、λ表达式:λ表达式的作用其实跟匿名方法没什么区别,可以将λ表达式理解成匿名方法的一种简洁表达方式。
匿名方法和λ表达式的引入,主要作用在于可以使得程序的表达更加简洁,但把这两个东西作为C#语言一个新的特征就有那么一点王婆卖瓜的味道了.其实所谓的范型、匿名方法等很多所谓的C#的新东西都是从C++中拿来重新包装一下而已,思想上并没有本质的进步(题外话:我们中国程序员很多时候都是被这种似是而非的新技术驱赶着跑)。
下面是一个简单的测试例子:
private void button1_Click(object sender, EventArgs e)
{
//Teacher是一个类,包含部门id和姓名两个字段.
var teachers = TestDataMgt.GetTeachers();//获取一个Teacher列表.
//一般方法(委托的典型调用方式),Select需要一个委托参数,该委托的定义:
//Func<TSource,TResult>(TSource obj)
//var depts2 = teachers.Select(new Func<Teacher,int>(FuncB)).Distinct();
#region 使用匿名方法调用.
//Func<Teacher, int> bb = delegate(Teacher T)
//{
// return T._deptId;
//};
//var depts2 = teachers.Select(bb).Distinct();
#endregion
//使用λ表达式,非简洁方式
//var depts2 = teachers.Select((T) => { return T._deptId; }).Distinct();
//等价于
var depts2 = teachers.Select(T=>T._deptId).Distinct();
foreach (var el in depts2)
{
this.richTextBox2.Text += el.ToString() + "/r/n";
}
}
private int FuncB(Teacher obj)
{
return obj._deptId;
}
分享到:
相关推荐
λ表达式之争ScalavsJava8Java开发Java经验技巧共5页.pdf.zip
λ表达式在Java中的应用
在JVM中没有匿名函数或Lambda表达式的概念。JVM知道是字节码。字节码是一个严格的OO规范。由语言的创造者和编译者通过这些限制来创建新的、高级的语言元素。 我们第一次遇到Lambda表达式是需要在Takipi中增加对...
解析器当前提供了一些语法糖,以使λ表达式的读取变得不那么麻烦,例如,较少依赖括号,更多地依赖于表达关联性,以及将λ表达式序列缩写为具有多个参数的单个λ表达式。 解析器支持变量名的UTF-8
通过多个示例详细演示了.Net中C#语言lambda表达式的基本用法,主要包括三个方面内容: 1.什么是lambda表达式 2.理解lambda表达式 3.使用lambda表达式
DapperDal - 简单易用的微 ORM 类库,数据访问层基类Introduction基于 Dapper、Dapper-Extensions 构建的微型 ORM 类库,提供一个包含增、删、改、查等常用方法的数据访问层基类,支持用 Lambda 表达式书写查询和...
我国是一个水土流失问题相对严重的国家...结果显示:相对于模型理论值λ=0.2时的模拟效果,在该流域λ=0.3时模拟值更加接近实测值,数模型效率系数E由-16.77提升到-1.03,精度大大提高,所以率定λ=0.3为该流域最适初损率。
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包...
λ表达式可以被当做是一个Object(注意措辞)。λ表达式的类型,叫做“目标类型(target type)”。 λ表达式的目标类型是“函数接口(functional interface)”,这是Java8新引入的概念。 它的定义是:一个接口,...
PLAM(对URE榄BDA演算)是探索,确定和评估各种λ表达式的工具。 用pLam编写的代码可以在pLam的shell中交互执行,也可以存储在扩展名为.plam的文件中,并可以随时运行。 在import/目录中,已经实现了许多有用的λ...
CST丛书18算例04_电大天线仿真(250λx250λx100λ)
λ射线仪表pdf,λ射线仪表
• LINQ 概览 • 访问数组 • 访问集合 • 查询投影 • 使用λ 表达式 • 查询操作符
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包...
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包...
论文研究-基于直觉模糊λ-Shapley Choquet积分算子TOPSIS的多属性群决策方法.pdf, 提出一种改进的逼近理想解排序(TOPSIS)方法, 即直觉模糊λ-Shapley Choquet积分算子...
干扰素λ在天然免疫中的作用,卢银平,李慧,干扰素λ(Interferon lambda,IFN-λ)为2003年新发现的新型干扰素,属于新增的Ⅲ型干扰素,分别是IFN-λ1(IL-29)、IFN-λ2(IL-28A)、IFN-λ3(IL-28B)。IFN-
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包...
λ-演算的语法和语义
优秀的文本编辑工具 EverEdit v3.4.1-x32λ.zip - 解包大小为 8.5 MBEverEdit v3.4.1-x32λ.zip - 解包大小为 8.5