泛型是一个在很多语言中都有相似结构的东西,主要的优点有:
- 性能
- 类型的安全性
- 命名约定
1.性能
这里写一个例子先:
public T GetDocument()
{
T doc = default(T);
//do something
return doc;
}
- 所有的类都是引用类型,结构体或者基本数据类型都是值类型,所以如果单纯的用泛型类型,不能使用null赋值,因为null只能用于引用类型,这时需要用default关键字。
- 一个list,引用类型和值引用相互转换需要进行装箱和拆箱操作,所以如果在创建开始的就规定只能是值类型,则避免了装箱和拆箱操作,增加系统处理数据的速度和性能 。
2.安全性
var list = new List<int>();
list.Add(88);//right
list.Add("string");//wrong
- 规定了list内存储的数据类型,则避免了添加错数据引起的不必要的bug。
3.命名约定
- 泛型通常用T座位前缀
- 如果没有特殊的要求,泛型允许用任意类替代,且只使用了一个泛型类型,就可以用字符T作为泛型类型的名称。
public class List<T>{ }
public class LinkedList<T>{ }
- 如果泛型类型有特殊的要求(比如,它必须实现一个接口或者派生自基类),或者使用了两个或者多个泛型类型,就应给泛型类型使用描述性的名称。
public delegate void EventHandler<in TEventArgs>(object sender,TEventArgs e);
public delegate TOutput Converter<in TInput, out TOutput>(TInput from);
下面再介绍一些泛型类相关的东西
1.泛型类约束
看下面的代码:
public class DocumentManager<TDocument> where TDocument : IDocument
{
}
- 这个类就要求,泛型TDocument 必须继承接口IDocument,通过这种方式,约束类的一些具体功能。
- 以下是约束要求:
约束 | 说明 |
---|---|
where T: struct | 对于结构体的约束,T必须是值类型 |
where T: class | T必须是引用类型 |
where T: IFoo | T必须实现接口IFoo |
where T: Foo | T 的基类必须是Foo |
where T: new() | T 必须有默认的构造函数 |
where T1: T2 | T1必须派生自T2 |
2.泛型类的继承
- 子类的泛型类型必须与父类相同,或者指定父类的泛型类型。
public class Base<T>{}
public class Child<T> : Base<T> { }
public class Child<T> : Base<string> { }
3.静态成员
public class StaticDemo<T>
{
public static int x;
}
public void Main()
{
StaticDemo<int>.x = 4;
StaticDemo<string>.x = 5;
StaticDemo<double>.x = 6;
}
- 每个不同的类型T,他们的static的关键字的值也可以不同,这里需要注意!
网友评论