C#2.0之细说泛型
C#2的头号亮点 : 泛型
在C#1中,Arraylist总是会给人带来困扰,因为它的参数类型是Object,这就让开发者无法把握集合中都有哪些类型的数据。如果对string类型的数据进行算术操作那自然会报错,但是遺憾的是在編譯期不会给你任何的提示
C#2中引入的泛型极其耀眼,甚至有些人会因为泛型而忽略C#2中其它新加入的特性
回到上面的问题,ArrayList带来的不仅仅是上面那些困扰,Object是所有类型的基类,但是我们在开发中它幾乎不会有它的身影,因为它包容一切,但是我们需要使用int做算术操作的时候就发生了问题,就是强制类型转换。当我们需要使用string的subString方法IDE也不会给你任何提示,因为它是Object类型。
泛型带来的就是这样革命性的改变,允許你的参数类型为泛型类型。回到ArrayList,泛型的典型就是List<T>了,而T就是泛型类型,它是一个未綁定类型(不明确的)。但是在我们使用的时候需要进行指定
List<string> strList = new List<string>();
这时我们去访问它的元素时就会有string数据类型的智能提示,我们可以輕松的点出subString方法。这时 List<string>就是已构造 的泛型类型。而且因为是显示的,也不会有类型转换的问题。性能上也是大大的提高,这时我们把运行时需要检查的提前到了编译时
开放封闭类型
这是一个比较绕的概念,看名称比较迷糊其实很容易理解。
泛型类型虽然也是类型,而T就是泛型类型,但它是开放的,可以是string,int,class等。开放类型无法创建实例,因为不知道创建什么实例,而封闭类型可以创建实例,封装类型就是指定了实际的数据类型,比如<string>
泛型约束
泛型类型也不总是任意数据类型都可以的,在开发的时候我们常常需要对传入的实际类型进行把握,如果外部使用时传入了意外的类型,那么就会引发BUG。
引用类型约束
如果我们希望数据类型是引用类型,那么我们可以 where T: class
值类型约束
如果我们希望数据类型是值 类型,那么我们可以 where T: struct
構造函數约束
我们希望数据类型是拥有无参的构造函数,那么我们可以 where T: new()
转换类型约束
我们希望数据类型是可以转换为我们想要指定的数据类型,比如某个基类的子类,某个接口的实现。我们可以 where T: Person
我们还可以根据实际需要进行组合约束,但是需要注意的是不是所有的约束都可以组合在一起,比如 约束不可以既是引用类型约束又是值类型约束。
泛型方法类型实参的类型推断
需要注意的是,这并不是我们常用的var类型推断,而是泛型方法的类型推断。
比如list<string>.Add("小明"); 这时小明很明显是一个字符串,那么这段代码就可以简化成 list.Add("小明");
高级泛型
这部分主要讨论的是泛型的效率问题与反射部分
都知道,相比较arrayList,泛型不会有拆箱装箱的过程,除了这些他们在内存中存儲的方式也是不一样的。比如ArrayList的byte和List<byte>。ArrayList会为每一个字节进行装箱并存儲已装箱值的引用。而List<byte>没有額外的引用存儲。他们看起来如下图
对于静态类型与静态字段还有静态構造函數, 我们都知道他们只会初始化一次,并且之后不会发生改变。对于泛型来说同一个泛型参数类型确实如此 ,每个封闭类型都有自己的静态字段集。它们是独立的。
比如 List<int> a;
List<string> b;
List<object > c;
List<int> d;
我们可以看到a与d是一个泛型参数类型,它们是静态构造函數只会运行一次,但是b、c、a会走三次,因为类型不一样。
JIT编译器处理泛型的时候,会把值类型翻译成不同的本地码,而引用类型翻译成共享的本地码。因为引用具有相同的大小。而值类型并不是。
我们在使用foreach的时候会感到很便利,有时候我们也会自己实现一个迭代器,这很简单,只要去实现IEnumerable<T>接口与IEnumerator<T>接口即可,但是如果我们发现泛型的接口又实现着非泛型的接口。如果没有问题,泛型接口都应该继承一个对应的非泛型接口,这样就可以实现协变性,在之前的C#版本中也会适用。
泛型存在的不足
C#的泛型设计的非常的巧妙,但是也有一些存在的不足之处。
泛型可变性(协变、逆变)的缺乏
在面向对象开发中我们可以用子类去New基类,这是没有问题的,但是对于泛型来说是不可以的,可以看到代码第一行是报错的。泛型不支持可变性,它们是不变体,这是为了类型安全着想
但是我们可以通过其它方法来实现可变性。最简单的使用泛型接口,和编写輔助类。在4.0中有了其它的解决方法
缺乏操作符约束
我们想要对泛型实参进行算术运算,但是并不是所有的类型都可以进行算术运行的。也没有类似于 + - / *这种操作符的约束。我们可以使用表达式树和动态特性解决此问题
缺乏泛型属性、索引器、成员类型
这很直观 ,上面所说的都无法使用泛型,我们不可以
Public T Property<T>{get;set;}
当然这个是无解的。因为至少我们开发的时候不会有这样的需求
C#2.0之细说泛型的更多相关文章
- 【C#复习总结】细说泛型委托
1 前言 本系列会将[委托] [匿名方法][Lambda表达式] [泛型委托] [表达式树] [事件]等基础知识总结一下.(本人小白一枚,有错误的地方希望大佬指正) 系类1:细说委托 系类2:细说匿名 ...
- .NET 4.0中的泛型协变和反变
转自:http://www.cnblogs.com/Ninputer/archive/2008/11/22/generic_covariant.html 随Visual Studio 2010 CTP ...
- .NET 4.0中的泛型协变和逆变
随Visual Studio 2010 CTP亮相的C#4和VB10,虽然在支持语言新特性方面走了相当不一样的两条路:C#着重增加后期绑定和与动态语言相容的若干特性,VB10着重简化语言和提高抽象能力 ...
- .NET 4.0中的泛型逆变和协变
转载自:http://www.cnblogs.com/Ninputer/archive/2008/11/22/generic_covariant.html:自己加了一些理解 随Visual Studi ...
- Spring框架入门之Spring4.0新特性——泛型注入
Spring框架入门之Spring4.0新特性——泛型注入 一.为了更加快捷的开发,为了更少的配置,特别是针对 Web 环境的开发,从 Spring 4.0 之后,Spring 引入了 泛型依赖注入. ...
- .NET 4.0中的泛型的协变和逆变
转自:http://www.cnblogs.com/jingzhongliumei/archive/2012/07/02/2573149.html 先做点准备工作,定义两个类:Animal类和其子类D ...
- 转载.NET 4.0中的泛型的协变和逆变
先做点准备工作,定义两个类:Animal类和其子类Dog类,一个泛型接口IMyInterface<T>, 他们的定义如下: public class Animal { } public ...
- Spring4.0开始的泛型依赖
参考资料: http://www.cnblogs.com/solverpeng/p/5687304.html 视频地址:https://edu.51cto.com/course/1956.html 一 ...
- 【C#复习总结】细说表达式树
1 前言 系类1:细说委托 系类2:细说匿名方法 系列3:细说Lambda表达式 系列4:细说泛型委托 系列5:细说表达式树 系列6:细说事件 涛声依旧,再续前言,接着用大佬的文章作为开头. 表达式树 ...
随机推荐
- UIImagePickerController照片选取器
记录于2013/7/4 加入框架: MobileCoreServices.framework MediaPlayer.framework 导入头文件: #import <MediaP ...
- centos docker 升级至最新稳定版--摘自官网
亲测好使 删除老版本的docker sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ do ...
- node03
1.express处理post请求 借助body-parse中间件,其实最终我们也不会使用这个 对于get请求,无需中间件,用req.query即可返回相应的数据 但是post我们尝试借助中间件处理 ...
- 微信小程序开发---逻辑层(App Service)
再说逻辑层之前,先说说微信小程序框架(MINA) 小程序开发框架的目标是通过尽可能简单.高效的方式让开发者可以在微信中开发具有原生APP体验的服务. 框架提供了自己的视图层描述语言WXML和WXSS, ...
- 4.21Linux(2)
2019-4-21 22:46:55 今天买了阿里云服务器1年的 116大洋!!! 但是有个服务器感觉很爽!!!!Linux系统还是很有意思的!!!! 直接贴上笔记! 越努力,越幸运!永远不要高估自己 ...
- 32 ArcToolBox学习系列之数据管理工具箱——属性域(Domains)的两种创建及使用方式
属性域分为两类,一种是范围域,一种是编码的值,下面将两个一起介绍,其中涉及到的编码,名称,只是试验,并非真实情况. 一.首先新建一个文件型地理数据库,将数据导入或者是新建要素类都可以 二.打开ArcT ...
- Nuget私有服务搭建实战
最近更新了Nuget私有服务器的版本,之前是2.8.5,现在是2.11.3. Nuget服务器的搭建,这里有篇很详细的文章,跟着弄就好了: https://docs.microsoft.com/en- ...
- 【RL-TCPnet网络教程】第5章 PHY芯片和STM32的MAC基础知识
第5章 PHY芯片和STM32的MAC基础知识 本章节为大家讲解STM32自带的MAC和PHY芯片的基础知识,为下一章底层驱动的讲解做一个铺垫. 5.1 初学者重要提示 5.2 ...
- Java Bloom filter几种实现比较
英文原始出处: Bloom filter for Scala, the fastest for JVM 本文介绍的是用Scala实现的Bloom filter. 源代码在github上.依照性能测试结 ...
- Python代码缩进与测试模块
一.Python代码缩进 Python 函数没有明显的 begin 和 end ,没有标明函数的开始和结束的花括号.唯一的分隔符是一个冒号 ( : ),接着代码本身是缩进的. 例如:缩进 bui ...