新手易犯的典型缺陷--C#

这段时间花了点时间整理了几个新手易犯的典型缺陷(专门针对C#的),可是我的的力量毕竟有限缺陷的覆盖面比较窄,有些缺陷的描述也不够准确,这里先贴出来看看能不能集思广益,收集整理出更多的典型缺陷。目标就是但愿刚入门.NET的新手看了以后能少走些弯路。数据库

1 及时释放资源

CLR托管环境扮演了垃圾回收的角色,因此你不须要显式释放已建立对象所占用的内存。但这不意味着你能够忽略全部的使用过的对象。许多对象封装了其余类型的系统资源(例如,磁盘文件,数据链接,网络端口)。保持这些资源的使用状态会急剧的耗尽系统的资源,削弱性能而且最终致使程序出错。当你打开一个文件、网络端口或者数据链接时,当你再也不使用这些资源时,应该尽快显式释放这些资源。
另外针对资源的操做,通常须要增长异常捕获处理(Try..Catch),这时别忘记在finally中进行资源释放,以确保在捕获异常时也能够正常释放资源。网络

2 正确中止多线程

FileStream fs = File.Open(…);
Try{…} Finally{ fs.Close;}

假设如上代码在工做线程中,已经进行到finally里面,这个时候UI线程调用了该线程的Abort()方法,则颇有可能fs.Close尚未执行的时候,工做线程跳出finally代码块了。这样你的fs就永远不会被Close了。
大多数状况下,finally会永远被被执行,但不包括调用Thread.Abort所引起的ThreadAbortException异常,鉴于此理由,不建议使用Abort。
要正确中止线程,不在于调用者采用了什么行为(不要直接使用Thread.Abort()),而更多依赖于工做线程是否能主动响应调用者的中止请求。
大致机制是,若是线程须要被中止,那么线程自身就应该负责给调用者开放Cancel的接口。多线程

3 类型转换相关

  • 若是从数据库中读取某个值,有数据时是int类型,没有数据的话获取到的是null,类型强转则会异常。因此通常不多用强转,用的话也必须作一个异常捕获,避免程序异常。
  • 在强转很差的状况下,咱们建议使用TryParse方法,该方法已经对Parse方法进行了异常处理。
  • 也能够用Convert,一样须要进行异常捕获;其实,凡是涉及到类型转换,序列化等操做的地方,都须要捕获异常;

4 字符串操做问题

在对字符串操做中,若涉及大量拼接操做建议使用StringBuilder。若使用String会带来明显的性能损耗。缘由在于string对象是个很特殊的对象,它一旦被赋值就不可改变。在运行时调用String类中任何拼接操做(如赋值、”+”等),都会在内存中建立一个新的字符串对象,也意味着要为该新对象分配新的内存空间。性能

5 const常量修改致使的问题

当程序引用其余dll中的const常量时要特别引发注意。
若修改了此dll中的const常量后,要从新编译引用了此dll中这个const常量的全部程序,不然程序中使用的这个常量值将和dl中的不一致。
另外若是使用readonly代替const能够解决这个问题,不须要从新编译,由于const是编译型常量,而readonly是运行时常量。ui

6 C#编译目标平台问题

当程序依赖的dll的编译的目标平台是X86,则程序自己的编译目标平台也必须是X86(而不是默认选项Any CPU),不然64位电脑将没法运行。线程

7 跨线程访问控件

在开发界面程序时,会遇到比较耗时的操做,为了程序的友好性,咱们通常会在任务线程中执行耗时操做,并将执行信息显示在主UI线程。
假如直接在任务线程中操做主UI线程中的控件,这样极易出现异常,报“不能在其余线程中修改建立控件线程的值”,若是设置了禁止编译器对跨线程访问作检查,就不会报错,可是会出现没法预知的问题。此时建议采用委托或匿名委托的方式实现。code

8 从新抛出异常的正确方式

try
{
    //do something
}
catch(Exception ex)
{
    throw;
}

正确的写法是throw,不要用throw ex,不然会清空stacktrace,没法定位到真正异常代码的位置。对象

相关文章
相关标签/搜索