当前位置:首页 > Windows程序 > 正文

深入理解C#中的泛型(二)

2021-03-28 Windows程序

   接着深入理解C#中的泛型(一),这篇文章主要讲解泛型类、泛型方法、泛型与集合。

泛型类

   如果我们想对一个类的所有泛型方法进行统一参数约束,我们把约束条件加在类上,此时这个类便成为泛型类,如下:

public class SortHelper<T> where T : IComparable

泛型方法

   如果一个类中只有某个方法使用了泛型,这时我们自然会想到:有没有办法把参数T加到方法上,而非整个类上,也就是降低T作用的范围。答案是可以的,我们称这样的方法为泛型方法,如下:

public class SortHelper { //参数为T的冒泡排序 public void BubbleSort<T>(T[] array) where T : IComparable { int length = array.Length; for (int i = 0; i <= length - 2; i++) { for (int j = length - 1; j >= 1; j--) { //对两个元素进行交换 if (array[j].CompareTo(array[j - 1]) < 0) { T temp = array[j]; array[j] = array[j - 1]; array[j - 1] = temp; } } } } }

   尽管BubbleSort()是一个泛型方法,但在使用上与普通方法没有任何区别。

泛型与集合

   说起泛型,我们就不得不提到集合类型,因为使用泛型能够极大地提高集合类型的性能和安全性。

   避免隐式的装箱和拆箱

ArrayList list = new ArrayList(); const int ListSize = 3; for (int i = 0; i < ListSize; i++) { list.Add(i); } for (int i = 0; i < ListSize; i++) { int value = (int)list[i]; Console.WriteLine(value); }         上述代码是“可以运行的代码”,而非“好的”代码。因为ArrayList类型为了包含任何类型,所有它接受的参数为所有类型的基类Object,Object是一个引用类型,而int是一个值类型,因此当调用list.Add(i)时,,存在一个装箱的操作。同理,当从ArrayList中获取元素时,又需要进行一个拆箱的操作:int value=(int)list[i]。这两个操作是相对耗时的,尤其是当集合类型包含的元素比较多或值类型比较大的时候。

   通过使用泛型,由于集合中的元素类型在编译时已经确定,就避免了装箱和拆箱的操作,这样显著提高了集合类型的性能。   

List<int> list = new List<int>(); const int ListSize = 3; for (int i = 0; i < ListSize; i++) { list.Add(i); } for (int i = 0; i < ListSize; i++) { int value = (int)list[i]; Console.WriteLine(value); }

   编译时的类型安全

ArrayList list = new ArrayList(); int i = 100; list.Add(i); string value = (string)list[0];     大家一看就能发现这段代码有问题,因为类型不匹配。可惜的是,编译器无法知道,因为对它来说,不管是int还是string,它们都是Object类型。对于上面的问题,编译器无能为力,因为它认为其是合法的,编译可以顺利通过,只有在运行时才会跑出异常。

   通过使用泛型集合,这种情况将不复存在,当试图进行类似上面的转换时,根本无法通过编译:

List<int> list = new List<int>(); int i = 100; list.Add(i); string value = (string)list[0]; //编译错误        到此,关于C#中泛型的理解讲解完毕,希望可以帮助大家进步。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69170.html