c# in depth之泛型的类型约束详细
类型约束
1.引用类型约束
这种约束(表示成T:class,必须是为类型参数指定的第一个约束)用于确保使用的类型实参是引用类型,这可能是任何类,接口,数组,委托或者已知是引用类型的另一个类型参数。
例如 struct RefSample<T> where T:class
有效的封装类型包括:
RefSample<IDisposable>;
RefSample<string>;
RefSample<int[]>;
无效的封装类型包括:
RefSample<Guid>
RefSample<int>
2.值类型约束
这种约束(表示成T:struct)可以确保使用的类型实参是值类型,其中包括枚举。但是,它将可空类型排除在外。
例如 class ValSample<T> where T:struct
有效的封装类型包括:
ValSample<int>
ValSample<FileMode>
无效的封装类型包括:
ValSample<object>
ValSample<string>
3.构造函数类型约束
这种约束(表示为T:new(),必须是所有类型参数的最后一个约束)仅核对所有类型实参有一个无参的构造函数,这个构造函数可用于创建类型的实例。这适用于:所有的值类型;所有非静态、非抽象、没有显示声明的构造函数的类;显示声明了一个公开的无参构造函数的所有非抽象类。
例子:
public T CreateInstance<T>() where T:new()
{
return new T();
}
有效的实例包括
CreateInstance<int>()
CreateInstance<object>()
无效的实例
CreateInstance<string>()
因为string没有无参构造函数
没有办法规定类型参数必须具备其他构造函数的签名,例如不能指定类型参数必须拥有一个以单个字符串作为参数的构造函数。
4.转换类型约束
这种约束允许你指定另一个类型,类型实参必须可以通过一致性引用或者装箱转换隐式地转换为该类型。还可以规定一个类型实参必须可以转换为另一个类型实参,这称为类型参数约束。
例子
class Sample<T> where T:Stream
有效:Sample<Stream> (一致性转换)
无效:Sample<string>
class Sample<T> where T:IDisposable
有效:Sample<SqlConnection>(引用转换)
无效:Sample<StringBuilder>
class Sample<T> where T:IComparable<T>
有效:Sample<int> (装箱转换)
无效:Sample<FileInfo>
class Sample<T,U> where T:U
有效:Sample<Stream,IDisposable>
无效:Sample<string,IDisposable>
任何类型都不能直接派生自多个类。对于这样的约束,要么是永远无法满足的,要么它的一部分是多余的。
5.组合约束
没有任何类型既是值类型又是引用类型。所以像这样的组合是禁止的。另外,由于每一个值类型都有一个无参构造函数,所以假如已经有一个值类型约束,就不允许再指定一个构造函数约束。如果存在多个转换类型约束,并且其中一个为类,那么它应该出现在接口的前面,而且我们不能多次指定同一个接口。不同的类型参数可以有不同的约束,它们分别由一个单独的where引入
有效的例子
class Sample<T> where T:class,IDisposale,new()
class Sample<T> where T:struct,IDisposable
class Sample<T> where T:class where U:struct,T
class Sample<T> where T:Stream where U:IDisposable
无效的例子
class Sample<T> where T:class,struct
class Sample<T> where T:Stream,class
class Sample<T> where T:new(),Stream
class Sample<T> where T:IDisposable,Stream
class Sample<T> where T:XmlReader,IComparable,IComparable
class Sample<T> where T:struct where U:class,T
class Sample<T> Stream,U:IDisposable
本文整理自:c# in depth
IDisposable接口用法请参阅:
http://blog.sina.com.cn/s/blog_66998b3f0100vwkn.html
c# in depth之泛型的类型约束详细的更多相关文章
- swift 泛型的类型约束
总结: 1.类型约束只能添加到泛型参量上面 2.关联类型是泛型参量: 3.关联类型可以通过 协议.关联类型名称的形式引用: func allItemsMatch<C1: Container, C ...
- Scala 基础(十六):泛型、类型约束-上界(Upper Bounds)/下界(lower bounds)、视图界定(View bounds)、上下文界定(Context bounds)、协变、逆变和不变
1 泛型 1)如果我们要求函数的参数可以接受任意类型.可以使用泛型,这个类型可以代表任意的数据类型. 2)例如 List,在创建 List 时,可以传入整型.字符串.浮点数等等任意类型.那是因为 Li ...
- 编写高质量代码改善C#程序的157个建议[优先考虑泛型、避免在泛型中声明静态成员、为泛型参数设定约束]
前言 泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能.基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型,确保了类型安全.委托 ...
- [转] C# 泛型类型参数的约束
啊.紫原文C# 泛型类型参数的约束 在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制 ...
- JavaBean 内省API BeanUtils工具 泛型 xml xml约束
1 什么是JavaBean?有何特征? 1)符合特定规则的类 2)JavaBean分二类: a)侠义的JavaBean .私有的字段(Field) .对私 ...
- 转载c#泛型 类型参数的约束(c#编程指南)
在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制称为约束.约束是使用 where 上 ...
- swift的类型约束
关键词: 类型与功能绑定.类型指定.访问控制. 类型约束的本质: 1.是否强制指定具有某些特征的类型:看类型构造器的定义本身是否对类型有约束: 2.访问控制:类型构造器的功能分为通用功能和约束功能: ...
- C#泛型类的类型约束
是使用泛型时,T默认情况下是不可以被初始化的,只能通过传值来赋值,这个时候可以使用类型约束来保证T是可以被约束的. .NET支持的类型参数约束有以下五种: where T: struct //T必须是 ...
- C# 泛型类型参数的约束
在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制称为约束.约束是使用 where 上 ...
随机推荐
- svn笔记
安装部署 1.yum install subversion 2.创建svn版本库目录 mkdir -p /svn 3.创建版本库 svnadmin create /svn/fengchao/ ...
- tar 基础
如何安装---> 出门右转百度. 1.基本使用方式 tar [option] desc_file source_file desc_file 表示要生成的打包文件:source_file 表示需 ...
- Solr入门之SolrServer实例化方式
随着solr版本的不断升级, 差异越来越大, 从以前的 solr1.2 到现在的 solr4.3, 无论是类还是功能都有很大的变换, 为了能及时跟上新版本的步伐, 在此将新版本的使用做一个简单的入门说 ...
- 基于visual Studio2013解决算法导论之030二叉查找树
题目 二叉查找树 解决代码及点评 // 12二叉查找树.cpp : 定义控制台应用程序的入口点. // // 3 - 10二叉搜索树查找.cpp : 定义控制台应用程序的入口点. // #in ...
- BZOJ 1260: [CQOI2007]涂色paint( 区间dp )
区间dp.. dp( l , r ) 表示让 [ l , r ] 这个区间都变成目标颜色的最少涂色次数. 考虑转移 : l == r 则 dp( l , r ) = 1 ( 显然 ) s[ l ] = ...
- 如何改变c盘的访问权限
1.在文件夹或文件图标上面点击鼠标右键,再点击属性2.打开文件夹属性选项卡,按顺序单击:安全 > 高级 >所有者 > 编辑,选中Administrators用户组(或者你的用户所在的 ...
- Python中的循环与跳出
--start-- for循环: for i in range(3): user_input = input("Your username:") passwd = int(inpu ...
- 高级特性(6)- 高级Swing
6.1 列表 6.1.1 JList构件 6.1.2 列表模式 6.1.3 插入和移除值 6.1.4 值的绘制6.2 表格 6.2.1 简单表格 6.2.2 表格模型 6.2.3 对行和列的操作 6. ...
- SPOJ 11840. Sum of Squares with Segment Tree (线段树,区间更新)
http://www.spoj.com/problems/SEGSQRSS/ SPOJ Problem Set (classical) 11840. Sum of Squares with Segme ...
- android开发隐藏了actionbar仍然短暂闪现的解决方法
有时候我们在代码里隐藏了actionbar,在打开应用时,仍然短暂闪现下actionbar,用户体验很不好. 最简单的方法是 在AndroidManifest.xml中设置主题中配置不显示titl ...