前些天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. 【转】用Python实现各种排序算法

    以下代码均为python3版本的代码 # 冒泡排序 # 比较相邻的元素大小,将小的前移,大的后移,就像水中的气泡一样,最小的元素经过几次移动,会最终浮到水面上. def bubbleSort(list ...

  2. shell-自动更改LINUX服务器IP

    #!/bin/bash echo  echo   ==  fi i= newgateway= newhostname= cat >>$ipfile<<EOF IPADDR=&q ...

  3. Factstone Benchmark

    [问题描述] Amtel已经宣布,到2010年,它将发行128位计算机芯片:到2020年,它将发行256位计算机:等等,Amtel坚持每持续十年将其字大小翻一番的战略.(Amtel于2000年发行了6 ...

  4. jquery中append跟prepend的用法

    jquery中append和prepend的用法 append   是插入到元素中,并放到元素内的最后面prepend  是插入到元素中,并放到元素内的最前面例$("body"). ...

  5. Gradle Android Studio basic

    1. change gradle version in gradle/wrapper/gradle-wrapper.properties  change distributionUrl=http\:/ ...

  6. 错误:Method not found: 'Void System.Web.UI.ScriptResourceDefinition.set_LoadSucce

    vs2012开发,再把.net 4.5降成4.0.部署到2003 服务器上就报错了. 在网上查了下,老外说:这个方法.net4.0不支持. 后面发现是发布方式错了,用项目里的发布,不要直接拷贝文件过去 ...

  7. 初识ASP.NET CORE:二、优劣

    Which one is right for me? ASP.NET is a mature web platform that provides all the services that you ...

  8. .NET Remoting原理及应用实例:

    Remoting:(本文摘自百度百科) 简介:        什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方 式.从微软的产品角度来看,可以说Remoting就是DCOM的一种升 ...

  9. ajax无刷新上传图片

    页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...

  10. Correspondence / ˏkɔris'pɔndәns / dictionary10-800.doc

    I have taken courses in office administration, typing,reports and correspondence writing. Correspond ...