我最近正在使用一个DateTime对象,并写了这样的东西:
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
AddDays()的智能感知文档说它在日期后添加了一天,但它并没有这样做——它实际上返回了一个添加了一天的日期,所以你必须这样写:
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
这个问题以前已经困扰过我很多次了,所以我认为将最糟糕的c#陷阱分类会很有用。
下面的代码不会捕获. net中的异常。相反,它会导致StackOverflow异常。
private void button1_Click( object sender, EventArgs e ) {
try {
CallMe(234);
} catch (Exception ex) {
label1.Text = ex.Message.ToString();
}
}
private void CallMe( Int32 x ) {
CallMe(x);
}
对于评论(和反对票):
如此明显的堆栈溢出是极其罕见的。但是,如果发生异常,您将不会捕获异常,并且可能会花费几个小时试图查找问题的确切位置。如果SO出现在很少使用的逻辑路径中,特别是在web应用程序中,你可能不知道引发问题的确切条件,那么情况就会更加复杂。
这与这个问题的公认答案完全相同(https://stackoverflow.com/a/241194/2424)。答案上的属性getter本质上做的事情与上面的代码完全相同,并且在没有堆栈跟踪的情况下崩溃。
抛出收到异常
一个让许多新开发人员困惑的问题是重新抛出异常语义。
我经常看到如下代码
catch(Exception e)
{
// Do stuff
throw e;
}
问题是它会清除堆栈跟踪,并使诊断问题变得更加困难,因为您无法跟踪异常起源于何处。
正确的代码是不带参数的throw语句:
catch(Exception)
{
throw;
}
或者将异常包装在另一个异常中,并使用内部异常获取原始堆栈跟踪:
catch(Exception e)
{
// Do stuff
throw new MySpecialException(e);
}