前些天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. mgo中DBRef-数据查询测试

    下午对数据查询进行了代码测试: package main import ( "crypto/rand" "encoding/hex" "fmt&quo ...

  2. nc检测端口是否正常服务的一个命令

    最近碰到一个项目,前端用apache htttpd进行发布(80端口),通过双机负载均衡转发到后端的两个tomcat进行处理(8081和8082端口),现在需要随时监控这三个端口的情况,一旦down掉 ...

  3. TJI读书笔记13-内部类

    TJI读书笔记13-内部类 TJI读书笔记13-内部类 创建内部类 内部类和外部类的关系 .this和.new 内部类和向上转型 局部内部类 匿名内部类 匿名内部类的定义和初始化 使用匿名内部类来实现 ...

  4. 开发BBS论坛

    一.涉及表结构 web\model.py(首选需要注意表结构的设计,如果表结构设计出来了,软件的架构也就基本出来了) #!/usr/bin/env python # _*_ coding:utf- _ ...

  5. C++之jsoncpp学习

    最新由于客户端要用到jsoncpp,所以自己也跟着项目的需求学了一下jsoncpp.以前没用过xml,但是感觉接触json后,还蛮好用的. 参考地址 http://jsoncpp.sourceforg ...

  6. codeforces 361 A - Mike and Cellphone

    原题: Description While swimming at the beach, Mike has accidentally dropped his cellphone into the wa ...

  7. CLR VIA C#事件

    事件是类型的一个成员,用来在事情发生的时候通知注册了该事件的成员. 事件和观察者模式十分的相似,所以事件应该提供如下几种能力 1.能让对象的方法登记对他的关注 2.能让对象的方法取消对他的关注 3.能 ...

  8. SQL语句调优 - 统计信息的含义与作用及维护计算

    统计信息的含义与作用                                                                                          ...

  9. 生成prefix.pch文件

    (借鉴网络资源)

  10. (九) 一起学 Unix 环境高级编程 (APUE) 之 线程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...