编写高质量的代码使用泛型集合而非泛型集合C程序,提高#(建议20)

在软件开发过程中,收集是不可避免的,并在C #集合表示为一个数组和一个数字集合类。他们都有自己的优点和缺点,无论它是一个数组或集合类。如何使用一套好的是我们要在发展的过程中掌握技巧。不要小看这些技术。一旦您在开发中使用了错误的集合或set方法,应用程序就会脱离您的预期。

建议20:使用泛型集而非非泛型集

在建议1中,我们知道如果要使代码高效地运行,应该避免打包和解包,并尽量减少转换。不幸的是,这不是在微软提供给我们的第一代集合类型中完成的。在这里,我们看看ArrayList类的使用:


铝=新的列表(ArrayList);
al加(0);
al加(1);
添加(麦克);
foreach(Al var item)
{
console.writeline(项目);
}


上面的代码部分充分说明了我们可以编写程序有多糟糕。

首先,Add ArrayList需要一个对象的参数,所以,添加(1)将完成包装第一;其次,在foreach,穿越它,并将完成开箱。

在这段代码中,塑造和字符串作为值类型和引用类型将被迫变换在隐式方法的对象,然后在foreach循环转化。

同时,这个代码也非类型安全的:我们在ArrayList同时既有整数和字符串存储,但缺乏的编译时类型检查。虽然有时候也需要这样做,它应该尽可能的避免类型检查。缺乏使隐藏的错误在运行时间。集合类ArrayList抛出一个ivalidcastexception如果它执行的操作如下图所示:


铝=新的列表(ArrayList);
al加(0);
al加(1);
添加(麦克);
int=0;
foreach(Al int项)
{
=项目;
}


ArrayList也提供了一个可以接收阵列ICollection参数直接施工方法,如下图所示:


无功intarr =新的int { } { 0, 1, 2,3 };
ArrayList al =新的ArrayList(intarr);




这种方法的内部实现是不好的,如下图所示(以下insertrange法施工方法中调用):


公共虚InsertRange(int index,ICollection C)
{
如果(c = NULL)
{
把新的argumentnullexception(C
}
如果((指数。_size))
{
把新的argumentoutofrangeexception(指数
}
计数;
如果(计数> 0)
{
this.ensurecapacity(这个。_size +计数);
如果(指数小于这个。_size)
{
阵列。复制(这个。_items,指数,这个指数。_items,+计数,这。_size指数);
}
对象{数组=新对象{ } };
C.CopyTo(阵列,0);
Array.CopyTo(这个。_items,指数);
这_size =计数;
这_version + +;
}
}


一般来说,如果迭代,转换或装箱和拆箱的大集合,使用ArrayList这样的传统将对效率的影响非常大。鉴于此,微软提供对泛型的支持。一个封闭在括号<>泛型类型的使用,那么编译器和运行时将完成剩下的工作微软不推荐使用ArrayList类型,而是建议使用通用的实现,如清单。

请注意,非泛型集合的系统。收藏的命名空间,和对应的泛型集合是system.collections.generic命名空间下。

拟议代码的通用实现如下:


新的名单列表IntList =();
(1)添加IntList;
(2)添加IntList;
/ / intlist.add(Mike);
foreach(在IntList VAR项)
{
console.writeline(项目);
}


代码中注释的行不会被编译,因为迈克是不是整数,这里是类型安全的特性。

下面比较了非泛型集合和泛型集合在运行中的效率。


static void main(String { } args)
{
console.writeline(开始测试列表:);
TestBegin();
testarraylist();
TestEnd();
console.writeline(开始测试列表:);
TestBegin();
testgenericlist();
TestEnd();
}
静态变量collectioncount = 0;
静态秒表=空;
静态变量testcount = 10000000;
TestBegin(静态)
{
收集所有代码的即时强制垃圾收集
(GC。WaitForPendingFinalizers); / /线程执行结束队列中的驱动器(即一个析构函数)
(GC。收集); / /所有代码的垃圾收集,包括从队列中的终结器的对象
collectioncount = gc.collectioncount(0); / /返回垃圾收集在0码数
手表=新秒表();
手表,开始();
}

TestEnd(静态)
{
手表停止();
console.writeline(耗时:+ watch.elapsedmilliseconds.tostring());
console.writeline(垃圾收集:数字+(GC.CollectionCount(0)- collectioncount));
}

静态testarraylist()
{
铝=新的列表(ArrayList);
int = 0;
为(int i = 0;i < testcount;i++)
{
al加(一);
温度=(int);
}
al = null;
}

静态testgenericlist()
{
斯斯特=新的列表(列表);
int = 0;
为(int i = 0;i < testcount;i++)
{
斯斯特。添加(我);
温度=斯斯特{我};
}
斯斯特= null;
}


输出是:

开始测试ArrayList:

耗时:2375

垃圾收集数量:26

开始测试列表:

耗时:220

垃圾收集数量:5

以上介绍的高质量代码的编写提高C #程序——而非泛型集合的泛型集合的使用(推荐20),对高质量代码的建议1到157的准备,这将继续更新,敬请关注,谢谢。