C#函数式程序设计之泛型(下)

 

每当使用泛型类型时,可以通过where字句对泛型添加约束:

这个例子直观地声明了一个约束:类型T必须与ListItem<string>相匹配。泛型类型约束T:X表示T可以是X、X的派生对象或X的实现(假如X是一个接口)。换言之,假如类型T的一个实例为t,则可以把它赋给一个变量:X x=t;

约束可以使用具体的类型,但是在这些情形下,类型不可以是密封的。有几个特殊的关键字可以取代或补充类型声明符。关键字class表示此类型必须是一个引用类型,而struct表示它必须是一个值类型。当new()与class或者任何具体类型一起使用时,可以给这个类型定义一个默认的构造函数。

约束的最后一个应用是定义两个类型参数的关系。例如,对于类型参数的T和U,约束T:U表示T必须与U相容。

使用约束时,有一点必须记住:泛型的基本作用是提供一个类型安全的方法,使代码可以处理不同类型的数据。约束用得越多,则离这个思想越远,因为约束降低了灵活性。

C#函数式程序设计之其他泛型类型

除了方法与类外,结构体、委托和接口也可以使用类型参数。结构体和接口使用类型参数是显而易见的,其用法与类相似:

即使是委托,其用法也丝毫没有令人吃惊的地方:

使用了泛型后,这些委托几乎可以代表任何函数。

C#函数式程序设计之协变与逆变

如果一个操作保留了类型原来的顺序,则成为协变,如果颠倒它们的顺序,则称为逆变。所谓的类型顺序是指:通用类型的顺序值比专用类型的顺序值强。

下面这个例子说明C#支持协变,首先定义一个对象数组:

可以把不同的值插入到这个数组中,因为所有数据最终都是派生自.NET中的Object类型。换言之,Object是一个非常通用的类型,即它是一个强类型。接下来说明.NET支持协变,它把一个弱类型的值赋给强类型的变量:

变量objects属于object[]类型,它可以保存实际类型为string[]的值。仔细想想,我们希望如此,但是结果不是这样的,毕竟,虽然string派生自object,但是string[]并不是派生自object[]。尽管如此,由于本例中C#支持协变,这个赋值是可行的。

说明逆变思想需要一个比较复杂的例子:

Woman是从Person派生出来的类,现在分析如下两个函数:

其中一个函数作用于Woman类,另一个函数比较通用,作用于Person类。从Woman类可以定义以下两个委托和函数:

DoWork函数接受一个Woman参数和一个函数引用,后者也接受一个Woman参数。DoWork函数把Woman实例传递给委托。元素类型大小为:Person比Woman强,WorkWithPerson比WorkWithWoman强,为了应用逆变,在此认为WorkWithPerson比AcceptWomanDelegate强,看以下三行代码:

首先创建一个Woman实例,然后调用DoWork函数,把Woman实例和WorkWithWoman方法的引用地址传递给DoWork。后者显然是与委托类型AcceptWomanDelegate相容——两者都只有一个Woman类型参数,没有返回值。但第三行代码有点怪,根据AcceptWomanDelegate的要求,WorkWithPerson方法接受一个Person参数,而不是一个Woman参数。虽然如此,WorkWithPerson还是与委托类型相容,这是逆变的缘故。

因此,在委托类型下,强类型可以保存在弱类型的变量中。

变异也能应用在泛型中。如下代码:

以上代码并没有得到C#的支持,编译器会报如下错误:

在C#和.NET4.0中,泛型的变异支持已删除,现在要使用泛型类型参数,可以用新增的关键字 in 和 out。这两个关键字定义或限制某个类型参数的数据流动方向,允许变异发生。

 
 
分类: C#专题
 

C#函数式程序设计之泛型(下)的更多相关文章

  1. C#函数式程序设计之泛型

    Intellij修改archetype Plugin配置 2014-03-16 09:26 by 破狼, 204 阅读, 0 评论,收藏, 编辑 Maven archetype plugin为我们提供 ...

  2. C#函数式程序设计之泛型(上)

    在面向对象语言中,我们可以编写一个元素为某个专用类型(可能需要为此创建一个ListElement)的List类,或者使用一个非常通用.允许添加任何类型元素的基类(在.NET中,首先想到的是System ...

  3. C#函数式程序设计之局部套用与部分应用

    函数式设计的核心与函数的应用以及函数如何作为算法的基本模块有关.利用局部套用技术可以把所有函数看成是函数类的成员,这些函数只有一个形参,有了局部套用,才有部分应用.部分应用是使函数模块化成为可能的两个 ...

  4. C#函数式程序设计之用闭包封装数据

    如果一个程序设计语言能够用高阶函数解决问题,则意味着数据作用域问题已十分突出.当函数可以当成参数和返回值在函数之间进行传递时,编译器利用闭包扩展变量的作用域,以保证随时能得到所需要的数据. C#函数式 ...

  5. C#函数式程序设计之函数、委托和Lambda表达式

    C#函数式程序设计之函数.委托和Lambda表达式 C#函数式程序设计之函数.委托和Lambda表达式   相信很多人都听说过函数式编程,提到函数式程序设计,脑海里涌现出来更多的是Lisp.Haske ...

  6. C#函数式程序设计之惰性列表工具——迭代器

    有效地处理数据时当今程序设计语言和框架的一个任务..NET拥有一个精心构建的集合类系统,它利用迭代器的功能实现对数据的顺序访问. 惰性枚举是一个迭代方法,其核心思想是只在需要的时候才去读取数据.这个思 ...

  7. C#函数式程序设计之代码即数据

    自3.5版本以来,.NET以及微软的.NET语言开始支持表达式树.它们为这些语言的某个特定子集提供了eval形式的求值功能.考虑下面这个简单的Lambda表达式: Func<int, int, ...

  8. 转载C#函数式程序设计初探——基础理论篇

    转载网址:http://www.cnblogs.com/Hlia/archive/2013/04/20/3029701.html 个人认为,C#语言的某些设计并不非常适合函数式开发,比如它的类型推断并 ...

  9. 【Java心得总结四】Java泛型下——万恶的擦除

    一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...

随机推荐

  1. malloc,free简单的实现

    有关标准库首先简要malloc其原理:     标准库内部通过一个双向链表.管理在堆中动态分配的内存.     malloc函数分配内存时会附加若干(一般是12个)字节,存放控制信息.     该信息 ...

  2. 十天学Linux内核之第五天---有关Linux文件系统实现的问题

    原文:十天学Linux内核之第五天---有关Linux文件系统实现的问题 有时间睡懒觉了,却还是五点多醒了,不过一直躺倒九点多才算起来,昨晚一直在弄飞凌的嵌入式开发板,有些问题没解决,自己电脑系统的问 ...

  3. Javascript学习2 - Javascript中的表达式和运算符

    原文:Javascript学习2 - Javascript中的表达式和运算符 Javascript中的运算符与C/C++中的运算符相似,但有几处不同的地方,相对于C/C++,也增加了几个不同的运算符, ...

  4. 设置韩澳大利亚sinox弄winxp清除字体和界面美观

    澳大利亚开始与汉sinox一直以为接口暗淡,字体比较模糊,否winxp光明,导致眼比较辛苦的眼睛.比方说,可能不那么黯淡刺眼,有益眼睛,但我不能忍受字体模糊.即使调整分辨率,,但是字体模糊还是没有改观 ...

  5. 我学的是设计模式的视频教程——装饰图案,装饰图案VS代理模式

    课程视频 装饰模式 装饰模式VS代理模式1 装饰模式VS代理模式2 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 版权声明:本文博主原创文章,博客,未经同意不得转载.

  6. 霍夫曼(最优二叉树)和Java达到

    一.定义 一些定义: 节点之间的路径长度:在从节点树中的一个节点也经历分公司,这构成的两个节点之间的路径分支的数目后这就是所谓的路径长度 的路径长度:从树的根节点到树中每一结点的路径长度之和. 在结点 ...

  7. OCP-1Z0-051-标题决心-文章5称号

    5. Which SQL statements would display the value 1890.55 as $1,890.55? (Choose three .) A. SELECT TO_ ...

  8. linux_vim_最佳快捷键

    如何使用vi文本编辑器     vi由比尔·乔伊(Bill Joy)撰写,所有UNIX like均默认安装此文本编辑器.详细简介请点击维基中文. 1.首先复制一个文件到/tmp目录(本例中为复制根目录 ...

  9. iOS8开发~UI布局(二)storyboard中autolayout和size class的使用具体解释

    一.概要:前一篇初步的描写叙述了size class的概念,那么实际中怎样使用呢,以下两个问题是我们一定会遇到的: 1.Xcode6中添加了size class,在storyboard中怎样使用? 2 ...

  10. 【百度地图API】北京周边7日游——图标按路线轨迹行动

    原文:[百度地图API]北京周边7日游--图标按路线轨迹行动 任务描述: 春节就要来啦~酸奶小妹的妈妈要从遥远的重庆,来到北京过春节呢!酸奶小妹忙着给妈妈计划,北京周边的旅游线路.计划好路线后,就开始 ...