C# 开发者最经常犯的 8 个错误 已翻译 100%

oschina 投递于 2013/01/08 17:14 (共 9 段, 翻译完成于 01-08)
阅读 6409
收藏 55
C#
7
加载中
在和C#新手一起工作的时候,我注意到他们经常重复一些错误。这些错误,当你指出来的时候很容易理解。然而,如果一个开发者没有意识到这些错误,将会影响正在开发的软件的质量和效率,因此,我决定总结8个常见的错误。
凡程子
翻译于 2013/01/08 19:31
3

1. 使用字符串连接代替StringBuilder

在你向一个字符串追加新字符串的时候,字符串连接方法是可行的。但是这样会导致新的内存空间被创建。被追加的字符串会拷贝到新的内存单元。这样的效率很低。而我们使用StringBuilder的话,可以免去字符串拷贝的发生。感谢StringBuilder在连接字符串中带来的高效率,尤其是在多次追加的操作中。

//错误写法
List values = new List(){"This ","is ","Sparta ","!"};
string outputValue = string.Empty;
foreach (var value in values)
{
   outputValue += value;
}
//正确写法
StringBuilder outputValueBuilder = new StringBuilder();
foreach (var value in values)
{
   outputValueBuilder.Append(value);
}

enixyu
翻译于 2013/01/08 20:11
2

2. LINQ - 'Where' 条件中使用 'First', 代替使用 FirstOrDefault

很多程序员在做查找操作的时候喜欢用'Where'操作并通过'First'获取第一次出现的记录。这样的操作是不对的。因为'First'操作不会在'Where'条件中起到作用。而且,这样也不能确保记录一定被找到。如果'First'在没有记录返回的操作中使用,系统会返回默认值并且没有任何异常被抛出。

//错误的写法
List numbers = new List(){1,4,5,9,11,15,20,21,25,34,55};
return numbers.Where(x => Fibonacci.IsInFibonacciSequence(x)).First();
//部分正确的写法
return numbers.First(x => Fibonacci.IsInFibonacciSequence(x));
//正确的写法
return numbers.FirstOrDefault(x => Fibonacci.IsInFibonacciSequence(x));

enixyu
翻译于 2013/01/08 20:18
1

3. 当对象不可转换的场合中,通过'(T)'操作做类型转化代替使用 'as (T)' 。

对于软件开发人员来说,使用'(T)' 做类型转换,而不是使用 'as (T)' 是很常见的写法。实际上,这样通常不会带来危害,因为多数对象都是可转换的。但是,如果在很低的可能性还是发生的情况下,对象不能转换,那么使用 'as (T)' 才是正确的。 详细请查看 Prefix-casting versus as-casting in C# 

//错误
var woman = (Woman)person;
//正确
var woman = person as Woman;

enixyu
翻译于 2013/01/08 20:25
1

4.不使用映射重写属性

有许多强大的C#映射(例如 AutoMapper)。如果只有几行代码来重写属性,这绝对可以用映射来代替。即使一些属性不能直接复制,但总有一些其他的逻辑可以让映射成为一个很好的选择(映射能够在更大泛围内定义重写属性的规则)。

凡程子
翻译于 2013/01/08 19:52
1

5.错误地重新抛出异常

C#程序员使用“throw ex”来抛出一个异常经常会忘记对栈的跟踪,会使程序难以调试并且不能形成日志信息,如果简单地使用“throw”,那么数据将不会丢失,并且可以方便地检索整个异常的堆栈跟踪。

//错误
try
{
   //some code that can throw exception [...]
}
catch (Exception ex)
{
   //some exception logic [...]
   throw ex;
}
//正确
try
{
   //some code that can throw exception [...]
}
catch (Exception ex)
{
   //some exception logic [...]
   throw;
}
凡程子
翻译于 2013/01/08 19:42
1

6. 没有使用 ‘using’ 语句来销毁对象

很多C#的软件开发人员竟然不知道关键字 'using' 不单单只用于引入命名空间,而还有回收销毁对象的功能。如果你明确知道某个对象在进行完某些操作后,不再有用,需要回收,你可以使用'using' 语句来销毁对象。

//以下语句:
using(SomeDisposableClass someDisposableObject = new SomeDisposableClass())
{
   someDisposableObject.DoTheJob();
}
//和以下语句是一样效果:
SomeDisposableClass someDisposableObject = new SomeDisposableClass();
try
{
   someDisposableObject.DoTheJob();
}
finally
{
   someDisposableObject.Dispose();
}
enixyu
翻译于 2013/01/08 20:30
1

7. 除了对象集合外,使用'foreach' 代替 'for'

请牢记除了对象集合之外(例如数组),当你需要进行迭代操作的时候,使用'for' 会比使用 'foreach'效率更高。请参考Foreach vs For Performance 。

enixyu
翻译于 2013/01/08 20:34
1

8. 对数据库进行读取或保存操作的时候,使用多次的DB调用

这是非常常见的错误,尤其在初级开发人员当中。特别是在使用ORM框架的时候,例如Entity Framework和NHibernate。每次的DB的调用都会耗费资源,所以对DB的操作越少越好。你可以通过以下方式做到:

  • 使用fetching(贪婪加载)
  • 把DB操作封装在事务当中
  • 为了避免复杂的逻辑,可以把业务逻辑封装到存储过程中。

可以说,还有C#程序员经常会遇到的错误还有很多很多。如果你发现某项是你感兴趣的或者你需要分享你的看法,欢迎留下你宝贵的意见。

enixyu
翻译于 2013/01/08 20:42
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(16)

llkaximoduo
llkaximoduo
http://www.codeproject.com/Articles/6759/FOREACH-Vs-FOR-C 这个哪位大侠可以翻译下
范特彪西
范特彪西

引用来自“Eyu.Net”的评论

1.string.Concat高效好用
2.SingleOrDefault也很常用
3.as是很温柔,但是会悄悄地坑你一把
4.Automapper坑也比较多,特别是在持久对象面前
5.catch (Exception ex)本身就跟比较野蛮的做法,catch一般只处理自定义错误
6.using确实很好用
7.试问各位的集合有多大?for跟foreach真有差别?
8.贪婪加载、延时加载各有优劣,不能一概而论,适时而用
事物毕竟有锁,能少用就少用,做到One DbContext per request就行
好吧,我承认,我开发的时候,从来不用存储过程、触发器之类的东西
业务逻辑做到数据库,感觉怪怪的,维护也不方便

嗯嗯 现在看来 我是新手XD

看来我也是新手,因为我居然赞成你全部观点。
3322
3322

引用来自“luwenhua”的评论

没用过c sharp,觉得第6条比较搞怪

对于需要手动管理资源的对象,如:IO对象,可以自动调用close()等方法,等同于jdk7中的try(InputStream in=null){}
真幻的现实
真幻的现实
这篇文章很一般,各有各的使用场景,顶多是新手可能用错了场景而已
AT7
AT7
1.string.Concat高效好用
2.SingleOrDefault也很常用
3.as是很温柔,但是会悄悄地坑你一把
4.Automapper坑也比较多,特别是在持久对象面前
5.catch (Exception ex)本身就跟比较野蛮的做法,catch一般只处理自定义错误
6.using确实很好用
7.试问各位的集合有多大?for跟foreach真有差别?
8.贪婪加载、延时加载各有优劣,不能一概而论,适时而用
事物毕竟有锁,能少用就少用,做到One DbContext per request就行
好吧,我承认,我开发的时候,从来不用存储过程、触发器之类的东西
业务逻辑做到数据库,感觉怪怪的,维护也不方便

嗯嗯 现在看来 我是新手XD
ViperWhip
ViperWhip
第7条好像标题和结论反了
第6条的using,其实.Net的GC机制,引用访问不到了就会自动销毁的,不是全局变量就没问题
文少大哥哥
文少大哥哥
不错。
Gmail.com
Gmail.com

引用来自“luwenhua”的评论

没用过c sharp,觉得第6条比较搞怪

似乎在Java8里面也加入了类似的功能
RayLee
RayLee
7. 除了对象集合外,使用'foreach' 代替 'for'
是不是写反了,“使用'for'代替 'foreach' ”
encro
encro
建议名字改为c#的8个坑。。。
返回顶部
顶部