Welcome

首页 / 软件开发 / C# / 编写高质量代码改善C#程序的建议:泛型集合、选择集合和集合的安全

编写高质量代码改善C#程序的建议:泛型集合、选择集合和集合的安全2014-10-05 cnblogs aehyok前言

软件开发过程中,不可避免会用到集合,C#中的集合表现为数组和若干集合类。不管是数组还是集合类,它们都有各自的优缺点。如何使用好集合是我们在开发过程中必须掌握的技巧。不要小看这些技巧,一旦在开发中使用了错误的集合或针对集合的方法,应用程序将会背离你的预想而运行。

本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。本文主要学习记录以下内容:

建议20、使用泛型集合来替代非泛型集合

建议21、选择正确的集合

建议22、确保集合的线性安全

建议20、使用泛型集合来替代非泛型集合

http://www.cnblogs.com/aehyok/p/3384637.html 这里有一篇文章,是我之前专门来介绍泛型的。我们应尽量的使用泛型集合。因为泛型的确有它的好处:

1、提供了类型安全,在编译期间就可以检查错误

2、更重要的是大部分情况下泛型集合的性能比非泛型集合的性能都高很多。

下面我们来看一段简单的测试性能的代码:

class Program{static int collectionCount = 0;static Stopwatch watch = null;static int testCount = 10000000;static void TestBegin(){GC.Collect(); ////强制对所有代码进行即时垃圾回收GC.WaitForPendingFinalizers();////挂起线程,执行终结器队列中的终结器(即析构方法)GC.Collect();///再次对所有代码进行垃圾回收,主要包括从终结器队列中出来的对象collectionCount = GC.CollectionCount(0);///返回在0代中执行的垃圾回收次数watch = new Stopwatch();watch.Start();} static void TestEnd(){watch.Stop();Console.WriteLine("耗时:{0}",watch.ElapsedMilliseconds.ToString());Console.WriteLine("垃圾回收次数:{0}", GC.CollectionCount(0) - collectionCount);}static void TestArrayList(){ArrayList arrayList = new ArrayList();int temp = 0;for (int i = 0; i < testCount; i++){arrayList.Add(i);temp = (int)arrayList[i];}arrayList = null;} static void TestGenericList(){List<int> list = new List<int>();int temp = 0;for (int i = 0; i < testCount; i++){list.Add(i);temp = list[i];}list = null;}static void Main(string[] args){Console.WriteLine("开始测试ArrayList");TestBegin();TestArrayList();TestEnd();Console.WriteLine("开始测试List<T>");TestBegin();TestGenericList();TestEnd();Console.ReadLine();}}
执行结果如下

我上面测试的次数是10000000,可以发现,两者在垃圾回收次数和耗时都差距比较大,所以泛型集合有着非泛型集合无法超越的优势。所以还是尽量在我们的程序中使用泛型集合吧。

建议21、选择正确的集合

http://www.cnblogs.com/aehyok/p/3643928.html这里有一篇我刚写的关于集合的博文,主要是简单介绍了一下关于自己使用比较频繁的几个集合。

如果集合的数目固定并且不涉及转型,使用数组效率高,否则就是使用List<T>。

像使用数组、ArrayList、List<T>、Dictionary<key,value>这些集合的有点就是插入和删除数据效率比较高,缺点就是查找的效率相对来说低一些。

关于队列可以参考http://msdn.microsoft.com/zh-cn/library/System.Collections.Queue(v=vs.80).aspx

关于栈可以参考http://msdn.microsoft.com/zh-cn/library/System.Collections.Stack(v=vs.110).aspx

建议22、确保集合的线性安全

建议18中提到,foreach循环不能代替for循环的一个原因是在迭代过程中对集合本身进行了增删操作。将此场景移植到多线程场景中,就是本建议要阐述的重点:确保集合的线程安全。集合线程安全是指在多个线程上添加活删除元素时,线程之间必须保持同步。

下面我们来通过实例来更详细的查看一下,先简单定义一个实体类

public class Person{public string Name { get; set; }public int Age { get; set; }}
static List<Person> list = new List<Person>() { new Person(){ Name="aehyok",Age=25},new Person(){Name="Kris",Age=23},new Person(){Name="Leo",Age=26}};static AutoResetEvent autoSet = new AutoResetEvent(false);static void Main(string[] args){Thread t1 = new Thread(() => {///阻止当前线程autoSet.WaitOne(); foreach (var item in list){Console.WriteLine("t1:"+item.Name);Thread.Sleep(1000);}});t1.Start(); Thread t2 = new Thread(() => { ///通知t1可以执行代码autoSet.Set();Thread.Sleep(1000);list.RemoveAt(2);});t2.Start(); Console.ReadLine();}
再来简单分析一下这段代码,其实就是闲定义了一个List集合,然后又定义了一个 AutoRestEvent的实例,用于控制线程的。

接下来在Main函数中定义了两个线程,在线程一中将线程一暂停,然后当调用线程二的时候再来通知线程一继续运行。最终运行结果

本文URL地址:http://www.bianceng.cn/Programming/csharp/201410/45473.htm