黑马程序员--.NET泛型类

来源:互联网 发布:大学生java实训学校 编辑:程序博客网 时间:2024/06/13 11:40

Windows Phone 7手机开发Net培训期待与您交流!

说到泛型类,不得不提到装箱与拆箱。对值类型使用非泛型集合类,在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。

值类型存储在堆栈上,引用类型存储在堆上。C#类是引用类型,结构是值类型。.NET很容易把值类型转换为引用类型,所以可以在需要对象(对象是引用类型)的任意地方使用值类型。例如,int可以赋予一个对象。从值类型转换为引用类型称为装箱。如果方法需要把一个对象作为参数,而且传送了一个值类型,装箱操作就会自动进行。另一方面,装箱的值类型可以使用拆箱操作转换为值类型。在拆箱时,需要使用类型转换运算符。

ArrayList list = new ArrayList();

list.Add(44);  // boxing – convert a value type to a reference type

 

int i1 = (int)list[0];  // unboxing – convert a reference type to a value type

 

foreach (int i2 in list)

{

  Console.WriteLine(i2);   // unboxing

}

装箱和拆箱操作很容易使用,但性能损失比较大,迭代许多项时尤其如此。

在下面的例子中,List<T>类的泛型类型定义为int,所以int类型在JIT编译器动态生成的类中使用,不再进行装箱和拆箱操作:

List<int> list = new List<int>();

list.Add(44);  // no boxing – value types are stored in the List<int>

 

int i1 = list[0];  // no unboxing, no cast needed

 

foreach (int i2 in list)

{

  Console.WriteLine(i2);

}

泛型的另一个特性是类型安全。与ArrayList类一样,如果使用对象,可以在这个集合中添加任意类型。下面的例子在ArrayList类型的集合中添加一个整数、一个字符串和一个MyClass类型的对象:

ArrayList list = new ArrayList();

list.Add(44);

list.Add("mystring");

list.Add(new MyClass());

如果这个集合使用下面的foreach语句迭代,而该foreach语句使用整数元素来迭代,编译器就会编译这段代码。但并不是集合中的所有元素都可以转换为int,所以会出现一个运行异常:

foreach (int i in list)

{

  Console.WriteLine(i);

}

错误应尽早发现。在泛型类List<T>中,泛型类型T定义了允许使用的类型。有了List<int>的定义,就只能把整数类型添加到集合中。编译器不会编译这段代码,因为Add()方法的参数无效:

List<int> list = new List<int>();

list.Add(44);

list.Add("mystring");  // compile time error

list.Add(new MyClass());  // compile time error

 

原创粉丝点击