【转】译文:.net 程序员易犯的7个通病

今天看到一个文章,主要讲述几个C#程序员在写代码时容易犯的毛病,内容很简单,没啥技术含量,都是一些稍微注意下即可避免的问题。我把它翻译过来只是方便大家加深一下记忆(某些代码不好格式化,所以我以截图的形式显示,需要看实际代码的可以在原文地址中找到,标题不能出现#这个符号,得硬生生将C#改为.net,无语中)。

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

原文:7 Common Mistakes Made By C# Programmers

地址:http://www.codeguru.com/csharp/article.php/c17911/7-Common-Mistakes-Made-By-C-Programmers.htm#page-1

作者:V.N.S Arun

介绍

在编程中犯错是不可避免的。即使一个简单的错误也会产生昂贵的代价。所以最明智的做法是从中汲取经验,不再犯同样的错误。我会在这篇文章中强调一下我认为C#程序员在开发过程中最容易犯的7个通病。

格式化字符串

在C#编程中处理字符串类型时,很有可能犯那些代价高的错误。在.net框架中,字符串一直都是不可变类型。当一个字符串被修改时,它总是会创建一个全新的副本而不是修改原有的字符串。但大部分开发者都会像下面这个例子一样来格式化字符串:

640?wx_fmt=jpeg

上面的代码看起来确实非常的乱。再者,因为字符串是不可变类型,这种多次拼接操作会在内存中创建3个多余的垃圾字符串副本。

更好的做法是使用string.Format,因为它内部使用了可变类型的StringBuilder。同时,这样做也为编写整洁的代码打下基础。

640?wx_fmt=jpeg

嵌套异常处理

下面的代码展示了开发者打算编写的嵌套方法,其中每个方法都做了异常处理:

640?wx_fmt=jpeg

如果像上面的代码那样,相同的异常被多次处理或更有甚者,捕获异常后再重新抛出明显会增加性能开销。

我通过把异常的处理都统一放到MainMethod中的某个位置来避免上述情况,如下所示:

640?wx_fmt=jpeg

在大型集合中使用foreach

大部分开发者会使用foreach循环来替代for,因为foreach更易于使用。

然而在处理有大量数据的集合时,这会导致昂贵的开销。思考一下以下的这个例子,我分别使用了for和foreach来循环相同的datatable,同时也请检查一下图1.0中两个循环分别使用的时间

640?wx_fmt=jpeg

640?wx_fmt=jpeg

正如你看到的一样,forech循环是慢的,它需要花费大概两倍于for循环的时间。这是因为在foreach中,dt.Rows会访问datatable中所有的行。

当需要在更大的集合中进行循环时,总是用for就行了。

验证基本数据类型

大部分开发者并不知道用来验证像System.Int32这些基本数据类型的内建方法,最后往往会自定义一个实现。下面的函数就是一个通过自定义逻辑来验证给定的字符串是否数字的例子

640?wx_fmt=jpeg

由于该方法包含了try catch,所以它并不是最好的实现方式。更好的方法是使用下面所示的int.TryParse

640?wx_fmt=jpeg

在我看来使用 int.TryParse明显运行更快,代码更清晰。

处理实现IDisposable接口的对象

在.net框架中,释放一个对象和使用它一样重要。最理想的方式是在一个类中实现IDisposable接口中的Dispose()方法,这样我们在using完那个类的对象后,它就会因为dispose方法被调用从而被释放。

下面所示的是一个SqlConnection对象从创建、使用到被释放的例子:

640?wx_fmt=jpeg

在上面的方法中,connection的dispose是在finally块中被调用的,这样做是因为一旦发生异常,catch块就会被执行,之后finally块也会被执行来释放connection。所以,connection会一直驻留在内存中直到finally块被执行。在.net框架中,当资源不再使用时及时释放是基本的准则之一。

下面的代码展示了一种更好的调用dispose方法的方式:

640?wx_fmt=jpeg

当你像上述那样使用using块时,一旦代码执行退出了using块,对象的dispose方法会被马上调用。这样能够确保sqlconnection资源能够被最快释放。你应该也察觉这种使用方式对于到任何实现Disposable接口的类都凑效。

声明公有变量

听上去简单,但它的确会导致你误用已声明的公有变量和给你的类型带来没有预料到的使用方式。

思考一下以下的这个例子:

640?wx_fmt=jpeg

在上述例子中,MyAcoount类型有一个公共有型变量AccountNumber并在构造函数中被赋值。我们希望AccountNumber是只读、不可修改的,但是MyAccount类型没法去控制这种行为。

更好的方式是将类似于AccountNumber的公有变量改为属性,如下面所示:

640?wx_fmt=jpeg

在这里,MyAccount已经对AccountNumber属性有了很好地控制。现在它变为只读的,调用者无法再设置它的值了。

访问System.Data.DataTable中的值

我经常发现大部分程序员通过列索引来访问datatable中的数据,正如下面所示的那样:

640?wx_fmt=jpeg

在上面的情况中,如果sql数据查询中的列顺序更改了,那么你的应用程序肯定会崩溃掉。我们应该总是通过列名来查找相应的数据,正如下面所示的那样:

640?wx_fmt=jpeg

即使列的顺序改变了,上面的代码也不会崩溃掉。同时,我们通过使用常量在某个位置统一记录所有的列名,即使你以后列名变了,你只要修改代码中的一处地方即可。


posted @ 2018-03-05 00:00  天使不哭  阅读(81)  评论(0编辑  收藏  举报