您的位置:首页 > 其它

泛型(一)简介

2012-11-23 15:36 169 查看
纯属复习笔记,小总结:文字较多排版很糟糕的随笔,岁很难赏心悦目,但也知识啊,读书得细心看,仔细看,不能被披着文字的纸老虎给吓住,也不要被千篇一眨眼就过了

知识点梳理:

1.概述

熟悉面向对象编程的开发人员都深谙这种编程方式的好处,其中一好处就是"代码重用",他极大的提高了开发效率,也就是说它可以派生一个类,让它继承基类的所有能力,派生类只需重写虚方法,或添加一些新方法,就可以定制派生类的行为。

2.泛型快速入门
泛型:英文generic,-->对应的命名空间 System.Collections.Generic
泛型是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,即“算法重用”。
简单的说开发人员先定义好一个算法,比如排序、搜索、交换、比较或者转换等,但是定义算法的开发人员并不设定该算法要操作什么类型的数据:该算法可以广泛的应用于不同类型的对象。然后,另一个开发人员只要指定了算法要操作的具体数据类型,就可以开始使用这个现成的算法了。
例如,可用一个排序算法来操作Int32和String等类型的对象,或者用比较算法类操作Datetime和Version等类型的对象。
大多数的算法都封装在一个类型中,CLR允许创建泛型引用类型和泛型值类型,但不允许创建泛型枚举类型,除此之外,CLR还允许创建泛型接口和泛型委托。
方法偶尔也封装有用的算法,所以CLR允许在引用类型、值类型或接口中定义泛型方法

先看以简单例子
Framework Class Library定义了一个泛型列表算法,List<T>(读list of Tee),以下是精简过的源代码

[Serializable]
public class List<T>:IList<T>,ICollection<T>,IEnumerable<T>,IList,ICollection,Enumerable{
public List();
public void Add(T item);
public Int32 BinarySearch(T item);
public void Clear();
public Boolean Contains(T item);
public void Sort();
public void Sort(IComparer<T> comparer);
public void Sort(Comparison<T> comparison)
public T[] ToArray();
public Int32 Count{ get; }
public T this[Int32 index] { get;set; }
}


这里的T是种可以是任何变量的类型:专业术语->类型参数

Tip:MS的设计原则,泛型参数变量要么称之为T,要么至少以大写T开头(如TKey和TValue)

定义好泛型List<T>类型后,使用泛型类型或方法,指定的具体的数据类型称为类型参数(type argument)

泛型为开发人员提供以下优势:
1.源代码保护:不需要访问算法的源代码。
2.类型安全:若试图使用不兼容类型的一个对象,会造成编译时出错。
3.更加清晰的代码:由于强制类型安全,减少了转型次数。
4.更佳的性能:在有泛型之前,要想定义一个常规化的算法,他的所有成员要定义成Object数据类型。要用这个算法来操作值类型的实例,CLR必须在调用算法的成员之前对值类型实例进行装箱,装箱会造成在托管堆上的内存分配,从而造成更多的垃圾回收,进而损害程序的性能。

利用List算法和非泛型ArrayList算法性能比较

public static void ValueTypePerfTest() {
const Int32 count = 10000000;

using (new OperationTimer("List<Int32>"))
{
List<Int32> l = new List<Int32>(count);
for ( Int32 n = 0;  n < count;  n++)
{
l.Add(n);
Int32 x = l
;
}
l = null;//确保进行垃圾回收
}

using (new OperationTimer("ArraryList of Int32"))
{
ArrayList a = new ArrayList();
for (Int32 n = 0; n < count; n++)
{
a.Add(n);
Int32 x = (Int32)a
;

}
a = null;//确保进行垃圾回收
}
}

public static void ReferenceTypePrefTest() {
const Int32 count = 10000000;

using (new OperationTimer("List<String>"))
{
List<String> l = new List<String>(count);
for (Int32 n = 0; n < count; n++)
{
l.Add("X");
String x = l
;
}
l = null;//确保进行垃圾回收
}

using (new OperationTimer("ArraryList of Int32"))
{
ArrayList a = new ArrayList();
for (Int32 n = 0; n < count; n++)
{
a.Add("X");
String x = (String)a
;

}
a = null;//确保进行垃圾回收
}
}

internal sealed class OperationTimer : IDisposable {
private Int64 m_startTime;
private String m_text;
private Int32 m_collectionCount;

public OperationTimer(String text)
{
PrepareForOperation();

m_text = text;
m_collectionCount = GC.CollectionCount(0);

//这应该是方法的最后一个语句,从而最大程度保证计时的准确性
m_startTime = Stopwatch.GetTimestamp();
}

public void Dispose() {
Console.WriteLine("{0,6:###.00} seconds (GCs={1,3})  {2}",
(Stopwatch.GetTimestamp()-m_startTime)/
(Double)Stopwatch.Frequency,
GC.CollectionCount(0)-m_collectionCount,m_text
);
}
private static void PrepareForOperation() {
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}

}




输入结果证明将泛型List算法应用于Int32类型速度将比非泛型块很多

Framework类库中的泛型

泛型最明显的应用就是集合类。FCL已经定义了几个泛型集合类。其中大多数都在System.Collections.Generic和System.Collections.ObjectModel命名空间中。要使用线程安全的泛型集合类,可以去System.Collections.Concurrent命名空间寻找。
MS建议开发人员使用泛型集合类,并基于几个方面的原因,不鼓励使用非泛型集合类。
首先,非泛型集合类不是泛型的,所以无法像使用泛型集合类那样,获得类型安全、更清晰的代码以及更佳的性能。
其次,泛型类具有比非泛型类更好的对象模型。例如,虚方法的数量显著减少,从而获得更好的性能,另外,泛型集合类增添了一些新成员,为开发人员提供新的功能。

新的泛型接口并不是设计用来玩去取代旧的非泛型接口。许多时候,为了保证向后兼容性,我们不得不同时使用两者。例如,如果List<T>类只实现了IList<T>接口,就没有代码能将一个List<DateTime>对象看成一个IList了。
还应该注意System.Array类提供了大量的静态泛型方法
例如:AsReadOnly,BinarySearch,ConverAll,Exists,Find,FindAll,FindIndex,FindLast,FindLastIndex,ForEach,IndexOf,LastIndexOf,Resize,Sort和TrueForAll等
下面代码如何使用其中的一些方法



Wintellect的Power Collections库

MS的要求,Wintellect制作了Power Collections库,使CLR程序员也能使用C++标准模版库(STL)的部分集合类,详情访问Wintellect.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: