前些天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#的泛型委托与闭包函数的更多相关文章

  1. 委托、泛型委托、多播委托、匿名函数、lamda表达式、事件

    1.为什么要使用委托 将一个方法作为参数传递给另一个方法 2.委托概念 public delegate int 委托名(int a, int b); 声明一个委托类型,可以用访问修饰符修饰,deleg ...

  2. c# 匿名方法(函数) 匿名委托 内置泛型委托 lamada

    匿名方法:通过匿名委托 .lamada表达式定义的函数具体操作并复制给委托类型: 匿名委托:委托的一种简单化声明方式通过delegate关键字声明: 内置泛型委托:系统已经内置的委托类型主要是不带返回 ...

  3. Predicate<T>与Func<T, bool>泛型委托

    引用别人的: static void Main(string[] args) { List<string> l = new List<string>(); l.Add(&quo ...

  4. C#泛型委托,匿名方法,匿名类

    class Test { delegate K proxy<T, K>(T t, K k); //泛型委托,注意返回值的写法,返回值的类型K先于其声明proxy<T,K>中的K ...

  5. .NET中的Action及Func泛型委托

    委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调机制的实现基 ...

  6. C#基础:泛型委托

    泛型委托是委托的一种特殊形式,感觉看上去比较怪异,其实在使用的时候跟委托差不多,不过泛型委托更具有类型通用性. 就拿C#里最常见的委托EventHandler打比方.在.NET 2.0以前,也就是泛型 ...

  7. 使用.NET中的Action及Func泛型委托

          委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储.传递,之后在任何时刻进行调用,因此,C#中函数回调 ...

  8. C#中Predicate<T>与Func<T, bool>泛型委托的用法实例

    本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之用.具体如下: 先来看看下面的例子: 1 2 3 4 5 6 ...

  9. C#语法糖之第六篇: 泛型委托- Predicate<T>、Func<T>

    今天继续分享泛型委托的Predicate<T>,上篇文章讲了Action委托,这个比Action委托功不一样的地方就是委托引用方法是Bool返回值的方法,Action为无返回值.首先我们看 ...

随机推荐

  1. 使用Form Builder创建Form具体步骤

    使用Oracle Form Builder创建Form具体步骤 (Data Source为Table) 说明:当Block使用的Data Source为Table时,Form会自动Insert,Upd ...

  2. iOS 调用拍照、选择本地相册、上传功能---未完善。

    1.新建viewController 拖入一个Button,添加点击事件,使用代理方法 <UIActionSheetDelegate,UIImagePickerControllerDelegat ...

  3. XidianOJ 1112 Too stupid

    题目描述 某天 light由于太富而且太帅遭到了歹徒的袭击,现在他遇到了n个歹徒,准备对light施行不法行为,虽然light身体强壮,但是毕竟只有一个人肯定打不过那么多歹徒,但是高智商的light觉 ...

  4. checkbox绿色圆圈样式

    抄自: http://www.cnblogs.com/xyzhanjiang/p/3989836.html?utm_source=tuicool&utm_medium=referral < ...

  5. 记录今天学习python中for与while循环针对break和continue的用法

    python中有两个主要的循环for与while,其中针对这两个循环有两种不同的中断用法break与continue. 首先先看下面的循环代码: 1: for i in range(10):#变量i带 ...

  6. 动态ViewPager导航页面

    今天新学知识总计,个人信息,仅供参考: item设置: viewpager页面设置: <?xml version="1.0" encoding="utf-8&quo ...

  7. dojo 加载Json数据

    1.今天研究了dojo datagrid加载WebService后台传上来的数据.研究来研究去发现他不是很难.用谷歌多调试一下就好了. 2.看很多例子,这个例子能够更好的帮我解决问题:https:// ...

  8. linux Bash

    本文包含的命令:type.echo.evn.set.locale.read.declare / typeset.ulimit.alias.unalias.history.!.source.stty.c ...

  9. .NET实现高效过滤敏感查找树算法(分词算法):

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. Jquery 生成时钟

    $(function(){ showTime(); }): function showTime () { var curtime=new Date(); $(".getDateTime&qu ...