我花了一些时间整理了几个新手容易犯的典型缺陷(专门针对C#),但个人实力毕竟有限。缺陷的覆盖面比较窄,有些缺陷描述的不够准确,所以贴在这里,看看能不能集思广益,多收集一些典型的缺陷。目的是希望刚入门.NET的新手看完后能少走弯路。1及时释放资源CLR宿主环境起到了垃圾回收的作用,所以不需要显式释放创建对象占用的内存。但这并不意味着您可以忽略所有使用过的对象。许多对象封装了其他类型的系统资源(例如,磁盘文件、数据连接、网络端口)。继续使用这些资源会极大地耗尽系统资源、降低性能并最终导致程序错误。当您打开文件、网络端口或数据连接时,您应该在不再使用这些资源时立即明确释放它们。另外,对于资源操作,一般需要增加异常捕获处理(Try..Catch)。这个时候不要忘记在finally中释放资源,保证捕获到异常的时候可以正常释放资源。2正确停止多线程FileStreamfs=File.Open(…);Try{…}Finally{fs.Close;}假设以上代码在工作线程中,已经进入finally。这个时候UI线程调用thread()方法的Abort,很有可能是在fs.Close还没有执行完的时候,工作线程就跳出了finally代码块。这样你的fs永远不会被关闭。大多数情况下,finally总是会被执行,但不包括调用Thread.Abort引起的ThreadAbortException。因此,不建议使用Abort。线程的正确停止,并不依赖于调用者的行为(不要直接使用Thread.Abort()),更多的取决于工作线程是否能够主动响应调用者的停止请求。一般的机制是,如果线程需要停止,线程本身应该负责向调用者打开Cancel接口。3类型转换相关如果从数据库中读取一个值,如果有数据,就是int类型,如果没有数据,就会得到null,强制类型异常。所以强制转移一般很少用到,如果用到,必须进行异常捕获,避免程序异常。在强制转换不好的情况下,我们推荐使用TryParse方法,它已经对Parse方法进行了异常处理。也可以使用Convert,同样需要捕获异常;事实上,凡是涉及类型转换、序列化等操作的地方,都需要捕获异常;4字符串操作问题在字符串操作中,如果涉及到大量的拼接操作,建议使用StringBuilder。如果使用String,会带来明显的性能损失。原因是字符串对象是一个非常特殊的对象,一旦赋值就不能改变。在运行时调用String类中的任何拼接操作(如赋值、“+”等)都会在内存中创建一个新的字符串对象,这也意味着必须为新对象分配新的内存空间。5、const常量修饰引起的问题当程序引用其他dll中的const常量时要特别注意。如果修改了这个dll中的const常量,那么所有在这个dll中引用这个const常量的程序都必须重新编译,否则程序中使用的常量值会和dl中不一致。另外,如果用readonly代替const来解决这个问题,不需要重新编译,因为const是编译常量,readonly是运行时常量。6C#编译目标平台问题当程序依赖的dll的编译目标平台是X86时,程序本身的编译目标平台也必须是X86(而不是默认选项AnyCPU),否则64位电脑将无法运行。7跨线程访问控件在开发界面程序时,会遇到耗时操作。为了程序的友好性,我们一般在任务线程中执行耗时操作,在UI主线程上显示执行信息。如果直接在任务线程中操作UI主线程中的控件,很容易出现异常,报“创建该控件的线程的值不能在其他线程中修改”。会报错,但是会出现不可预知的问题。这时候推荐使用委托或者匿名委托。
