我最近正在使用一个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#陷阱分类会很有用。
enum Seasons
{
Spring = 1, Summer = 2, Automn = 3, Winter = 4
}
public string HowYouFeelAbout(Seasons season)
{
switch (season)
{
case Seasons.Spring:
return "Nice.";
case Seasons.Summer:
return "Hot.";
case Seasons.Automn:
return "Cool.";
case Seasons.Winter:
return "Chilly.";
}
}
错误呢?
不是所有的代码路径都返回一个值…
你在开玩笑吗?我打赌所有代码路径都返回一个值,因为这里提到了每个Seasons成员。它应该已经检查所有enum成员,如果一个成员在开关情况下是缺席的,那么这样的错误将是有意义的,但现在我应该添加一个默认情况下,这是冗余的,永远不会被代码达到。
编辑:
在对这个Gotcha进行了更多的研究之后,我看到了Eric Lippert写得很好的和有用的帖子,但它仍然有点奇怪。你同意吗?
这是一个超级陷阱,我浪费了2天的时间来解决问题。它没有抛出任何异常,只是用一些奇怪的错误消息使web服务器崩溃。我无法在DEV中重现这个问题。此外,项目构建设置的实验以某种方式使它在PROD中消失,然后它又回来了。我终于明白了。
如果你在下面这段代码中发现了问题,请告诉我:
private void DumpError(Exception exception, Stack<String> context)
{
if (context.Any())
{
Trace.WriteLine(context.Pop());
Trace.Indent();
this.DumpError(exception, context);
Trace.Unindent();
}
else
{
Trace.WriteLine(exception.Message);
}
}
所以如果你重视自己的理智:
! !永远不要给Trace方法添加任何逻辑!!
代码应该是这样的:
private void DumpError(Exception exception, Stack<String> context)
{
if (context.Any())
{
var popped = context.Pop();
Trace.WriteLine(popped);
Trace.Indent();
this.DumpError(exception, context);
Trace.Unindent();
}
else
{
Trace.WriteLine(exception.Message);
}
}