C#程序员最易犯的编程错误

2019-12-26 13:38:31王振洲

  为了利用好C#中的类型安全,你最好选择使用一个泛型接口,而不是使用非泛型的借口。泛型接口中的元素类型是你在在声明对象时指定的类型,而非泛型中的元素是object类型。当使用一个非泛型的接口时,C#的编译器不能对你的代码进行类型检查。同样,当你在操作原生类型的集合时,使用非泛型的接口会导致C#对这些类型进行频繁的装箱(boxing)和拆箱(unboxing)操作。和使用指定了合适类型的泛型集合相比,这会带来很明显的性能影响。

  另一个常见的陷阱是自己去实现一个集合类型。这并不是说永远不要这样做,你可以通过使用或扩展.NET提供的一些被广泛使用的集合类型来节省大量的时间,而不是去重复造轮子。 特别是,C#的C5 Generic Collection Library 和CLI提供了很多额外的集合类型,像持久化树形数据结构,基于堆的优先级队列,哈希索引的数组列表,链表等以及更多。

  常见错误8:遗漏资源释放

  CLR 托管环境扮演了垃圾回收器的角色,所以你不需要显式释放已创建对象所占用的内存。事实上,你也不能显式释放。C#中没有与C++ delete对应的运算符或者与C语言中free()函数对应的方法。但这并不意味着你可以忽略所有的使用过的对象。许多对象类型封装了许多其它类型的系统资源(例如,磁盘文件,数据连接,网络端口等等)。保持这些资源使用状态会急剧耗尽系统的资源,削弱性能并且最终导致程序出错。

  尽管所有C#的类中都定义了析构方法,但是销毁对象(C#中也叫做终结器)可能存在的问题是你不确定它们时候会被调用。他们在未来一个不确定的时间被垃圾回收器调用(一个异步的线程,此举可能引发额外的并发)。试图避免这种由垃圾回收器中GC.Collect()方法所施加的强制限制并非一种好的编程实践,因为可能在垃圾回收线程试图回收适宜回收的对象时,在不可预知的时间内致使线程阻塞。

  这并意味着最好不要用终结器,显式释放资源并不会导致其中的任何一个后果。当你打开一个文件、网络端口或者数据连接时,当你不再使用这些资源时,你应该尽快的显式释放这些资源。

  资源泄露几乎在所有的环境中都会引发关注。但是,C#提供了一种健壮的机制使资源的使用变得简单。如果合理利用,可以大增减少泄露出现的机率。NET framework定义了一个IDisposable接口,仅由一个Dispose()构成。任何实现IDisposable的接口的对象都会在对象生命周期结束调用Dispose()方法。调用结果明确而且决定性的释放占用的资源。