我最近正在使用一个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#陷阱分类会很有用。


当前回答

在调试环境中求值时,base关键字不能按预期工作:方法调用仍然使用虚拟分派。

当我偶然发现它时,我浪费了很多时间,我以为我遇到了CLR时空中的某种裂缝,但我后来意识到这是一个已知的(甚至有点故意的)bug:

http://blogs.msdn.com/jmstall/archive/2006/06/29/funceval-does-virtual-dispatch.aspx

其他回答

下面的代码不会捕获. 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本质上做的事情与上面的代码完全相同,并且在没有堆栈跟踪的情况下崩溃。

一些代码:

        List<int> a = new List<int>();
        for (int i = 0; i < 10; i++)
        {
            a.Add(i);
        }

        var q1 = (from aa in a
                  where aa == 2
                  select aa).Single();

        var q2 = (from aa in a
                  where aa == 2
                  select aa).First();

q1 -在这个查询中检查List中的所有整数; Q2 -检查整数,直到找到“正确的”整数。

抛出收到异常

一个让许多新开发人员困惑的问题是重新抛出异常语义。

我经常看到如下代码

catch(Exception e) 
{
   // Do stuff 
   throw e; 
}

问题是它会清除堆栈跟踪,并使诊断问题变得更加困难,因为您无法跟踪异常起源于何处。

正确的代码是不带参数的throw语句:

catch(Exception)
{
    throw;
}

或者将异常包装在另一个异常中,并使用内部异常获取原始堆栈跟踪:

catch(Exception e) 
{
   // Do stuff 
   throw new MySpecialException(e); 
}
TextInfo textInfo = Thread.CurrentThread.CurrentCulture.TextInfo;

textInfo.ToTitleCase("hello world!"); //Returns "Hello World!"
textInfo.ToTitleCase("hElLo WoRld!"); //Returns "Hello World!"
textInfo.ToTitleCase("Hello World!"); //Returns "Hello World!"
textInfo.ToTitleCase("HELLO WORLD!"); //Returns "HELLO WORLD!"

是的,这种行为是有记录的,但这并不能证明它是正确的。

mystring.Replace("x","y")

虽然它看起来应该对被调用的字符串进行替换,但实际上它返回了一个新字符串,替换完成后没有改变被调用的字符串。你需要记住字符串是不可变的。