c#集合与泛型

在应用程序中存储数据最简单的容器是数组,但无法满足数据的动态伸缩,为了摆脱这些数组的限制,.net基础类库发布了很多包含集合类的命名空间,集合类的尺寸是动态的,可以在运行时插入或者移除数据项,集合类包括两类:

1.非泛型集合:

主要位于System.Collections命名空间,包括ArraryList,BitArray,Stack,Queue等类,同时System.Collections.Specialized下的ListDictionary等类以及一些接口。

非泛型集合存在的问题:

1)性能问题:.Net支持两大数据类型:值类型和引用类型,有时候需要用某个类别的变量表示另外一个类别的变量,c#提供了装箱的机制将值类型的数据保存在引用类型中,装箱的实际定义为CLR会在堆上分配新的对象,将值类型的值赋予新的实例,并返回新的对象的引用。相反的操作为拆箱,拆箱是将保存在对象引用上的值转换回栈上相应的值类型,CLR会验证收到的值类型是否是装箱的值类型,如果是就将值赋值回本地值类型,如果不是则抛出异常。尽管装箱和拆箱都很方便,但带来的栈/堆内存的转移会导致性能问题。

2)类型安全问题

除了拆箱的时候我们需要记住装箱的值类型,还需要类型安全的容器来操作某些特定的数据类型,在引入泛型之前,需要通过手工创建强类型的集合类。

2.泛型集合

使用泛型集合可以解决上面的问题,包括性能的损失,泛型更类型安全,以及无需手工创建强类型的集合类,只需使用泛型集合并制定类型。

1)在创建泛型结构的时候需要在声明变量或者调用构造函数的时候指定类型参数,此时所有的占位符都将替换为类型参数。

2)非泛型类或者结构都支持泛型成员,在调用这种方法时需要指定类型参数,例如System.Array的sort静态方法包含一个相应的泛型方法sort<T>().

3)List<T>是泛型类中最常用的,可以动态的调整数据,以下举例说明具体的实现:

4)stack<T>类以后进先出的方式维护数据的集合,包含pop()和push(),从栈内压入或移除数据

5)Quenue<T>,队列以先进先出的方式访问数据,使用Enqueue()和Dequeue()添加数据和移除数据

6)SortedSet<T>类,这个类中的数据是排序的,在插入和移除数据之后仍然能自动排序,需要向其构造函数中传递一个实现了IComparer<T>,该接口定义了Compare方法。

 7)ObservableCollection<T>类表示能在添加、移除或者刷新整个列表时提供通知的动态数据集,合,ReadOnlyObservableCollection<T>的操作与之类似,不过是只读的。ObservableCollection《T>实现了一个名为CollectionChanged事件,该事件在插入新的数据或者移除数据时触发。

8)除了使用命名空间内包含的泛型类型后,也可以自定义泛型方法,以下定义了一个交换的泛型方法。

9)除了自定义泛型方法外,还可以自定义泛型结构和泛型类

10).net平台可以通过where关键字约束参数的类型

.NET支持的类型参数约束有以下五种:
where T : struct                               | T必须是一个结构类型
where T : class                                 | T必须是一个Class类型
where T : new()                               | T必须要有一个无参构造函数
where T : NameOfBaseClass              | T必须继承名为NameOfBaseClass的类
where T : NameOfInterface               | T必须实现名为NameOfInterface的接口

原文地址:https://www.cnblogs.com/qqvvn/p/9612271.html