为什么要使用泛型
- 性能优势 : 免去了装箱拆箱。 这个节省可不是一般的大啊..
- 如果类型将操作值类型,那么就会产生装箱和拆箱操作,使用泛型能防止装箱和拆箱操作。
- 泛型的强类型检查有助于快速查找错误
- 代码简洁 : N个类的东西一个泛型类搞定.. 跟容易维护和编写
- 安全。 当然你得写的兼容性差... 传什么都能执行那就完了
缺点
- 代码简洁 : 这是一把双刃剑, 大量使用泛型类 会使代码的可读性变得非常差 非常不容易维护
关于性能
其实书上比较了性能说的也比较清楚
这里也有一篇关于 姐夫赵的 泛型真的会降低性能吗
我就不在这里多做赘述了,泛型虽说提升不大 但是至少不会带来性能损失
泛型的协变逆变 这个系列完成之后 会专门去写一章 讨论一下
关于继承
其实泛型类的继承类 正常类的继承没有任何区别,只是多了个T罢了
不过书中提到了一种用法. 创建一个链表完全不同类型的链表
先定义一个基类
internal class Node
{
protected Node m_next;
public Node(Node next)
{
m_next = next; //一个构造 传入下一个节点
}
}
internal sealed class TypedNode<T> : Node
{
public T m_data;
public TypedNode(T data)
: this(data, null)
{
}
public TypedNode(T data, Node next)
: base(next)
{
m_data = data;
}
public override String ToString()
{
return m_data.ToString() +
((m_next != null) ? m_next.ToString() : null);
}
}
这样就可以传入有不同类型的 链节点
验证性与约束,虽然使用T ,但是还有必须有起码的约束 才能更安全,才能真正意义能使用
public static T Min<T>(T o1, T o2) where T : IComparable<T> {
return o2;
}
实例化Min 的类型就必须包含IComparable接口
public class aaa<T> where T : IList
{
public T a;
public T aaa1() {
return a;
}
}
他相比直接这样写
public class aaa
{
IList a;
public IList aaa1() {
return a;
}
}
好处就是 泛型能直接 返回 任意类, 而下面的接口这种却只能返回指定类
最大的差别就在这里
加上了约束之后, 你约束的东西能干什么。 你泛型类就能干什么
public class aaa<T> where T : class
{
public T a;
public T aaa1() {
return a;
}
}
这个时候 就可以直接写
T b = null;
因为 T = class
当然 如果在没有约束值类型引用类型的情况下
T b = null 是要报错的
因为 天知道 T = ?
万一 T 是 int
so 提供了一种方法
T b = default(T); null or 0
构造器的约束
public class a<T> where T : new() {}
T 必须有无参构造器。
关于比较
这还是要看约束是什么
比如 == null
T obj == null (如果T 是值类型 不会报错,不执行罢了)
下面是官方提供的泛型接口
ICollection<T>
IEnumerator<T>
IEnumerable<T>
IComparer<T>
IComparable<T>
IList<T>
IDictionary<K,V>
其实泛型单就语法上来说并不复杂
但是对于泛型的掌握程度(尤其是泛型类 泛型接口)
其实很能体现程序员的抽象能力
对泛型的使用有以下要注意的
- 通常,能够参数化的类型越多,代码就会变得越灵活,重用性就越好. 但是 太多的通用化会使其他开发人员难以阅读或理解代码
- 应用尽可能最多的约束,但仍使能够处理必须处理的类型,以保证安全性
大概就是这样吧