泛型(一)
泛型的目的:提高代码的可重用性和类型安全性。
泛型引语
重用性的表现,在最初接触开发的时候,总会有从数据库中取值并写如对象中,通常实现的方式是利用这样的代码: EntityClass obj = new EntityClass(); obj.ID = dataReader[0]==null?string.Empty:dataReader[“fieldname_ID”].toString();而实体类总是由多个字段组成的,因此实体类有多少个字段,我们就不的写多少行此类的代码,自从有了泛型,这样的工作就有缩减,可以通过下面的代码来实现重用:
private staticT GetDataSourceValue<T>(object dataSource, string fieldName, TdefaultValue)
{
T result = defaultValue;
if (dataSource is DataRow)
result = (T)((DataRow)dataSource)[fieldName];
else
result = (T)((DataReader)dataSource)[fieldName];
returnresult;
}
泛型术语
约束:对泛型类型参数的约束。
泛型方法:只有在方法具有自己的类型参数列表时,此方法才能称为泛型方法。
泛型类型和继承
泛型类型本质上还是一个类型,所以其可以从其他任何类型派生,也可以被继承和实现。指定类型实参,不会与层次发生关系。
代码示例:
public class Node
{
protected Node _next;
public Node(Node next)
{
this._next = next;
}
}
public class GenericNode<T> : Node
{
public T _data;
public GenericNode(T data)
: this(data, null)
{ }
public GenericNode(T data, Node next)
: base(next)
{
this._data = data;
}
public override string ToString()
{
return this._data.ToString() + "|" + (this._next != null ? this._next.ToString() : string.Empty);
}
}
泛型类型同一性
可以从泛型类型进行派生,基类指定了类型实参。为了简化下面这样的代码:
List<DateTime> list = newList<DateTime>(); 我们会定义这样一个类:
public seal class DateTimeList :List<DateTime> { } ;然后可以进行这样的定义:
DateTimeList list = new DateTimeList(); 但是需要注意的是这样做会丢掉代码的同一性和相等性,即: typeof(DateTimeList) != typeof(List<DateTime>) 。
为解决此问题,我们可以使用using指令,在代码文件首部定义此转移表达式:
usingDateTimeList = System.Collection.Generic.List<System.DateTime> ;并且typeof(DateTimeList)== typeof(List<DateTime>);
code explosion
CLR进行编译时需要为不同的方法/类型生成本地代码,若每一种泛型参数类型都需要生成一份代码,则程序集会增加很大,损害性能,这被称为code explosion
改善方法:
- 假定为一个特定的类型实参调用了一个方法,则当前的AppDomain中的相同类型的实参都会使用此方法。
- CLR认为所有的引用类型的实参是完全相同的。由于引用类型的变量实际是指向堆上的对象的指针。其操作都一样。