.NET中的范型与集合

2024-08-27 20:58
文章标签 net 集合 范型

本文主要是介绍.NET中的范型与集合,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    在学习设计模式的时候,我们用到了范型,在VB.NET机房重构的时候,我们又用到了范型,感觉范型就像一个集合Collections,而且集合ArrayList()非常好用,它可以盛放许多类型的数据(里面涉及到了拆箱与装箱),那么,范型与ArrayList()又有什么渊源哪?下面我讲一下C#中的范型与集合ArrayList()的区别。

    一、泛型简介:

    泛型(Generic Type)是.NET Framework2.0最强大的功能之一。泛型的主要思想是将算法与数据结构完全分离开,使得一次定义的算法能作用于多种数据结构,从而实现高度可重用的开发。通过泛型可以定义类型安全的数据结构,而没有必要使用实际的数据类型,这将显著提高系统性能并得到高质量的代码(因为可以重用数据处理算法,没有必要复制类型特定的代码。

    二、范型与ArrayList()的渊源关系

    拿C#编程为例,C# 是一个类型安全的语言,类型安全允许编译器(可信赖地)捕获潜在的错误,而不是在程序运行时才发现(不可信赖地,往往发生在你将产品出售了以后!)。因此,在C#中,所有的变量都有一个定义了的类型;当你将一个对象赋值给那个变量的时候,编译器检查这个赋值是否正确,如果有问题,将会给出错误信息。

    在.Net 1.1 版本(2003)中,当你在使用集合时,这种类型安全就失效了。由.Net 类库提供的所有关于集合的类全是用来存储基类型(Object)的,而.Net 中所有的一切都是由Object基类继承下来的,因此所有类型都可以放到一个集合中。于是,相当于根本就没有了类型检测。更糟的是,每一次你从集合中取出一个Object,你都必须将它强制转换成正确的类型(拆装箱)这一转换将对性能造成影响,并且产生冗长的代码(如果你忘了进行转换,将会抛出异常。更进一步地讲,如果你给集合中添加一个值类型(比如,一个整型变量),这个整型变量就被隐式地装箱了(再一次降低了性能),而当你从集合中取出它的时候,又会进行一次显式地拆箱(又一次性能的降低和类型转换)。

    在公共语言运行库和C# 语言的早期版本中,通用化是通过在类型与通用基类型Object 之间进行强制转换来实现的,泛型提供了针对这种限制的解决方案。通过创建泛型类,您可以创建一个在编译时类型安全的集合。使用非泛型集合类的限制可以通过编写一小段程序来演示,该程序利用.NET Framework 基类库中的ArrayList 集合类。ArrayList 是一个使用起来非常方便的集合类,无需进行修改即可用来存储任何引用或值类型。

    个人理解:当我们用C#或者VB.NET编写的代码想让机器执行时,是一种高级语言向低级语言转化的过程,由C#编写的代码转化成机器语言,这样机器才可以直接执行。执行的过程是:编译器将源码转化为微软中间语言MSIL,然后再由公共语言运行时(CLR)转化成机器语言。(如果不理解,可以点击此超链接)这样,机器就可以直接执行我们编写的代码了。如果不理解,可以看我的博客.NET框架。当编译器对源码进行编译时,就实现了上面所说的在编译阶段检查错误的功能。

   范型与集合相比,有以下几个优点。

   1、性能

   对值类型使用非泛型集合类,在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。装箱和拆箱的操作很容易实现,但是性能损失较大。假如使用泛型,就可以避免装箱和拆箱操作。

ArrayList list=new ArrayList();list.Add(20);            //装箱,list存放的是object类型元素,须将值类型转化为引用类型int i=(int)list[0];     //拆箱,list[0]的类型是object,要赋值就得把引用类型转化为值类型



   如果换成泛型编程,就不会有装箱和拆箱的性能损失。

List<T> list=new List<int>();
list.Add(20);    //因为指定了用int来实例化,因此不必装箱
int i=list[0];    //同样地,访问时也不需要拆箱,可以直接接受,不需要转化。


  2、类型安全。

    与ArrayList类一样,如果使用对象,可以在这个集合中添加任意类型。如果使用非泛型编程,如下代码,就有可能在某些情况下会发生异常。注意:编译时不出错,但运行时有错。

ArrayList list=new ArrayList();list.Add(20);list.Add("string");foreach(int i in list){Console.WriteLine(i);    //这里会有个异常,因为并不是集合中的所有元素都可以转化为int}


    如果该用泛型编程,则可以避免这种异常,让编译器检查出错误。

List<int> list=new List<int>();
list.Add(20);
lsit.Add("string");   //编译时报错,只能报整数类型添加到集合中


    3、二进制代码重用

  泛型可以定义一次,用许多不同的类型实例化,不需要像C++模板那样访问源代码。泛型可以在一种语言中定义,在另一种.NET语言中使用。

    4、代码的扩展

  因为泛型类的定义会放在程序集中,所以用某个类型实例化泛型泛型类不会在IL(微软中间语言)代码中复制这些类。但是,在JIT编译器把泛型类编译为内部代码时,会给每个值类型创建一个新类。引用类型共享同一个内部类的所有实现代码。这是因为引用类型在实例化的泛型类中只需要4字节的内存单元(32位系统),就可以引用一个引用类型。值类型包含在实例化的泛型类的内存中。而每个值类型对内存的要求都不同,所以要为每个值类型实例化一个新类。

   以上是本人对范型和集合做了一点点的比较,总的来说,利用范型可以定义类型安全的数据结构(编译器编译时检查错误),能提高代码的性能(减少拆装箱) ,可以复用,当然,代码扩展。 

这篇关于.NET中的范型与集合的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112767

相关文章

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

基于Redis有序集合实现滑动窗口限流的步骤

《基于Redis有序集合实现滑动窗口限流的步骤》滑动窗口算法是一种基于时间窗口的限流算法,通过动态地滑动窗口,可以动态调整限流的速率,Redis有序集合可以用来实现滑动窗口限流,本文介绍基于Redis... 滑动窗口算法是一种基于时间窗口的限流算法,它将时间划分为若干个固定大小的窗口,每个窗口内记录了该时间

.NET利用C#字节流动态操作Excel文件

《.NET利用C#字节流动态操作Excel文件》在.NET开发中,通过字节流动态操作Excel文件提供了一种高效且灵活的方式处理数据,本文将演示如何在.NET平台使用C#通过字节流创建,读取,编辑及保... 目录用C#创建并保存Excel工作簿为字节流用C#通过字节流直接读取Excel文件数据用C#通过字节

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像

Java基础回顾系列-第六天-Java集合

Java基础回顾系列-第六天-Java集合 集合概述数组的弊端集合框架的优点Java集合关系图集合框架体系图java.util.Collection接口 List集合java.util.List接口java.util.ArrayListjava.util.LinkedListjava.util.Vector Set集合java.util.Set接口java.util.HashSetjava

【408数据结构】散列 (哈希)知识点集合复习考点题目

苏泽  “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家    知识点 1. 散列查找 散列查找是一种高效的查找方法,它通过散列函数将关键字映射到数组的一个位置,从而实现快速查找。这种方法的时间复杂度平均为(

java集合的概述

集合就是一个容器,我们可以把多个对象放入的容器中。就像水杯(假设容量可以不断扩大)一样,你可以往水杯中不断地添加水,既然是水杯,你就不能往里添加沙子,也就是说集合中添加的对象必须是同一个类型的(引用类型,而不能是基本类型)。 看到集合的介绍会让我们的想起数组,那么集合和数组有什么区别呢? 首先,数组的大小是固定的,而集合理论上大小是不限的。 其次,数组既可以存储基本数据类型的数据,也可以存储