C#的泛型委托与闭包函数
前些天Wendy问我说Func<T, ResultT>是个什么意思,初学C#都觉得这样的写法很奇葩,甚至觉得这样写有点诡异,其实以我来看,这是体现C#函数式编程的又一个亮点。
从MSDN上我们可以找到这个所谓的泛型委托的解释。委托是C#较之于Java多出来的概念之一,C# 1.0的委托大体上看来就是一个函数指针,但是随着语言发展从委托衍生出来了多播委托和事件。
参考F#函数,我们其实更好理解C#里面的泛型委托。举个例子:
let x x y = x + y
这个F#的语句声明了一个接收两个整型参数并返回一个整型值的函数x。它的函数特征为
val x : x:int -> y:int -> int
F#借助强大的类型推断,我们可以像写数学函数一样书写函数,C#就不同了,C#并不是一门以函数是程序设计为主的程序设计语言,所以我们需要把类型给标注出来,于是就是:
Func<int, int, int> x = (j, k) => j + k;
可以看出来,我们写的Func<int, int, int>就是F#里所谓的函数的特征值。在函数式程序设计里,更强调不可变,比如在F#中,我们仅使用let绑定的值都属于不可变值,如果需要使用变量,那么我们需要诉之于可变性,也就是需要使用let mutable的绑定方法来绑定值。在函数是程序设计领域内并不欢迎使用可变值,因为这样可能带来更多的隐患,尤其是全局变量,牵一发而动全身会导致程序后期难以控制。
虽然现在C#对于作用域的控制比较严格,但是总有一些时候我们得初始化一堆变量,后面还在不断引用,稍不注意就可能产生意外的结局,但是借助泛型委托,我们可以把函数式程序设计的优点糅合进C#里。
举个例子:
class Complex
{
public Double Re{ get; set; } = 0;
public Double Im{ get; set; } = 0;
public Double Modulus => System.Math.Sqrt (Re * Re + Im * Im);
private static Func<Complex, Complex> RequestConjugate() => x => new Complex{ Re = x.Re, Im = -x.Im };
public Complex Conjugate() => RequestConjugate () (this);
}
注意到RequestConjugate,它只返回了一个泛型委托而不是真正返回了一个共轭复数。而Conjugate方法却很诡异RequestConjugate () (this),出现了两个括号,而第二个括号其实是传入了x作为参数,这样就实现了一个闭包,我们可以动态创建函数并把它当成返回值返回,并在需要使用的地方使用上。
似乎这个例子有点脱裤子放屁的感觉,直接
return一个Complex不就得了么...
C#的泛型委托与闭包函数的更多相关文章
- 委托、泛型委托、多播委托、匿名函数、lamda表达式、事件
1.为什么要使用委托 将一个方法作为参数传递给另一个方法 2.委托概念 public delegate int 委托名(int a, int b); 声明一个委托类型,可以用访问修饰符修饰,deleg ...
- c# 匿名方法(函数) 匿名委托 内置泛型委托 lamada
匿名方法:通过匿名委托 .lamada表达式定义的函数具体操作并复制给委托类型: 匿名委托:委托的一种简单化声明方式通过delegate关键字声明: 内置泛型委托:系统已经内置的委托类型主要是不带返回 ...
- Predicate<T>与Func<T, bool>泛型委托
引用别人的: static void Main(string[] args) { List<string> l = new List<string>(); l.Add(&quo ...
- C#泛型委托,匿名方法,匿名类
class Test { delegate K proxy<T, K>(T t, K k); //泛型委托,注意返回值的写法,返回值的类型K先于其声明proxy<T,K>中的K ...
- .NET中的Action及Func泛型委托
委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调机制的实现基 ...
- C#基础:泛型委托
泛型委托是委托的一种特殊形式,感觉看上去比较怪异,其实在使用的时候跟委托差不多,不过泛型委托更具有类型通用性. 就拿C#里最常见的委托EventHandler打比方.在.NET 2.0以前,也就是泛型 ...
- 使用.NET中的Action及Func泛型委托
委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调 ...
- C#中Predicate<T>与Func<T, bool>泛型委托的用法实例
本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之用.具体如下: 先来看看下面的例子: 1 2 3 4 5 6 ...
- C#语法糖之第六篇: 泛型委托- Predicate<T>、Func<T>
今天继续分享泛型委托的Predicate<T>,上篇文章讲了Action委托,这个比Action委托功不一样的地方就是委托引用方法是Bool返回值的方法,Action为无返回值.首先我们看 ...
随机推荐
- 27、初步探索echarts源码
1.首先发现随笔中凡是和echarts相关的点击率都特别高,于是乎就接着写了echarts因为感觉要转点击率 首先声明我并不是专业做前端的,所以如果有些说得不对的地方,希望前端大神们出来指正 首先发现 ...
- empty isset array_key_exists 的区别
empty: 参数为0或为NULL时(如上面列子),empty均返回TRUE,详细情况可以参见empty官方手册 isset: 参数为NULL时,返回FALSE,0与NULL在PHP中是有区别的,is ...
- ---Under Ubuntu 14.04
Thinprint provides driver-free printing. Do you wish to enable this feature? [yes] Disabling timer-b ...
- Add Binary <leetcode>
Given two binary strings, return their sum (also a binary string). For example,a = "11"b = ...
- protobuff 配合 libevent 在Linux 和windows 下的使用
protobuff 配合 libevent 在Linux 和windows 下的使用待补全. libprotobuf.lib libproto-lite.lib libprotoc.lib
- ueditor 发布到服务器提示“后端配置项没有正常加载,上传插件不能正常使用!”
原来是发布后缺少文件,直接从本地的复制过去就好了.
- ssh搭建后的简化
关于ssh如何搭建还有不懂得朋友可以参考以下网址:http://www.cnblogs.com/LarryBlogger/p/5841446.html 在这里我就不重复再讲了! ssh搭建后的简化 简 ...
- 关于 tomcat nio connector, servlet 3.0 async, spring mvc async 的关系
tomcat 的 org.apache.coyote.http11.Http11NioProtocol Connector 是一个使用 Java NIO 实现的异步 accept 请求的 connec ...
- 第一章 JacksonUtil 序列化与反序列化属性总结
1.json-lib与Jackson 关于json-lib与Jackson对比总结如下: 1).性能方面,Jackson的处理能力高出Json-lib10倍左右. 2).json-lib已经停止更新, ...
- iOS 1 到 iOS 10 ,我都快老了
iOS 1:iPhone诞生 虽然很难想像,但初代iPhone在问世时在功能方面其实远远落后于那时的竞争对手,比如Windows Mobile.Palm OS.塞班.甚至是黑莓.它不支持3G.多任务. ...