1.非泛型集合的问题
第一个,非泛型集合类中存储结构时,CLR必须执行大量的内存转换操作,降低运行时速度。(装箱与拆箱)
第二个,集合类不是类型安全的,因为他们是为了操作System.Object类而开发的。如果.net开发者需要创建高度类型安全的集合(如某容器只能容纳实现了某个接口的对象),需要手工创建一个全新的集合类。
2.装箱
把值类型数据保存在引用类型变量中。显式的将值类型分配给System.Object变量的过程。CLR会在堆上分配新的对象并且将值类型的值复制到那个实例上,返回给我们新分配在堆上的对象的引用。
3.拆箱
把保存在对象引用中的值转换回栈上的相应的值类型。
int x = 111;
object obj = x; //装箱
int y = (int)obj;//拆箱
4.类型安全问题
在拆箱的时候必须将数据拆箱为装箱之前声明的类型。其次例如ArrayList 可以保存任何类型,任何确保只能保存指定类型或兼容的类型,唯一方法就是创建自定义的全新集合类。
public class MyClass1
{
public string Name { get; set; }
public string Id { get; set; }
}
public class MyClass8 : IEnumerable
{
private ArrayList myArrayList = new ArrayList();
public MyClass1 GetMyClass1(int pos)
{
return (MyClass1)myArrayList[pos];
}
public void AddMyClass1(MyClass1 myCls1)
{
myArrayList.Add(myCls1);
}
public void Clear()
{
myArrayList.Clear();
}
public int Count { get { return myArrayList.Count; } }
public IEnumerator GetEnumerator()
{
return myArrayList.GetEnumerator();
}
}
虽然自定义的集合可以确保类型安全,但是必须为每一个希望包含的类型创建自定义集合。然而自定义集合并没有消除装箱/拆箱的性能损失。(j将上面的MyClass1类型换成int型)
5.泛型集合的优点
第一,提供了更好的性能,不会导致拆箱装箱的损耗
第二,类型是安全的
第三,大幅减少自定义集合类型的需要。
6.类、接口、结构、委托可以使用泛型,枚举类型不可以。
7.非泛型类或这结构都支持泛型成员(方法、属性),因此在调用这种方法时,你仍然需要指定占位符的值。如
Array.Sort<int>(myInts);
8.集合初始化语法
List<int> intList = new List<int> { 1, 2, 3, 4, 5 };
List<MyClass1> listMyCls1 = new List<MyClass1>
{
new MyClass1 { Id = "1", Name = "aaa" },
new MyClass1 { Id = "2", Name = "bbb" }
};
8.常见的泛型类
List<T>、Stack<T>、Queue<T>
SortedSet<T>类:
该类中的项是排序的,在插入和移除项之后,也能自动确保排序正确。可以向其构造函数传递一个实现了IComparer<T>泛型接口的参数
9.创建自定义泛型方法
private void Swap<T>(ref T a, ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
调用该泛型方法时,当泛型方法需要参数时,我们可以选择省略类型参数,因为编译器会基于成员参数推断雷翔参数。
调用:
bool a = true; bool b = false;
swap<bool>(ref a, ref b); //或者 Swap(ref a, ref b); //类型参数推断只在泛型方法至少有一个参数的时候起作用。
如:
private string ShowType<T>()
{
return typeof(T).FullName;
}
调用:
int a = 0;
ShowType<int>();//这里必须要指定T的类型参数。
10.自定义泛型结构和类
public class Point<T>
{
private T x;
private T y;
public Point(T x, T y) //泛型构造函数
{
this.x = x;
this.y = y;
}
public T X //泛型属性
{
get { return x; }
set { x = value; }
}
}
11.泛型约束
可以对给定的类型参数添加一组约束,编译时将检查这些约束。
where T:struct 必须为结构
where T:class T必须为引用类型
where T:new() T必须包含一个默认的构造函数,存在多个约束,该约束必须列在末尾。
where T:BaseClass T必须派生子BaseClass
where T:IInterface T必须实现接口IInterface,多个接口使用逗号隔开