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为无返回值.首先我们看 ...
随机推荐
- CmdBuild
cmdBuild官网地址:http://www.cmdbuild.org/it 下载.功能和安装说明:http://www.cmdbuild.org/en/download 扩展组件: shark-c ...
- 开发常用小demo 整理
pc懒加载 https://github.com/ningmengxs/Lazy_loading 元素滑动 js 效果 https://github.com/ningmengxs/elem ...
- Cocos2d-JS 自定义loading界面
[转]http://blog.csdn.net/et_sandy/article/details/41415047 环境: win7 64位 Cocos2d-JS v3.1 Cocos Code ID ...
- Docker常用操作
启动容器并安装package docker run xxx apt-get -y xxx 其中-y要加上避免无法交互 批量删除容器 docker ps -a | awk '{print $1}' |x ...
- textview 多行 省略号
TextView自带的可以通过 android:ellipsize="end" android:singleLine="true"实现单行省略, 多行显示: ...
- Appium学习路-打包apk和ipa篇
间隔这么长时间再去写Appium的学习篇是有原因的,因为在想要用appium测试ios时,发现appium只能测试debug版本的ipa包.然后就需要自己去学习打包了啊.然后就对xcode各种不了解, ...
- cocos2d-x 坐标系
OPenGL坐标系:原点为屏幕左下角 屏幕坐标系:原点在屏幕左上角
- elasticsearch Java API汇总
http://blog.csdn.net/changong28/article/details/38445805#comments 3.1 集群的连接 3.1.1 作为Elasticsearch节点 ...
- Python全栈之路-----基础篇
Python诞生 Python是著名的”龟叔“Guido van Rossum(吉多·范罗苏姆)在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Python语法很多来自C,但又受到 ...
- Spring MVC Web框架
1. Spring MVC简介 Spring MVC是java EE平台请求驱动类型的轻量级Web框架,使用了MVC设计模式的思想,spring框架的主要优势之一就是分层架构,分层架构允许选择使用 ...