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


当前回答

静态构造函数在锁定状态下执行。因此,从静态构造函数调用线程代码可能会导致死锁。 下面是一个例子:

using System.Threading;
class Blah
{
    static void Main() { /* Won’t run because the static constructor deadlocks. */ }

    static Blah()
    {
        Thread thread = new Thread(ThreadBody);
        thread.Start();
        thread.Join();
    }

    static void ThreadBody() { }
}

其他回答

到目前为止我最糟糕的一个,我今天才想出来……如果你重写object。Equals(object obj),你会发现:

((MyObject)obj).Equals(this);

与以下行为不同:

((MyObject)obj) == this;

一个会调用你的覆盖函数,另一个不会。

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写得很好的和有用的帖子,但它仍然有点奇怪。你同意吗?

数组实现IList

但是不要执行它。当您调用Add时,它会告诉您它不起作用。那么,为什么一个类在不支持接口的情况下还要实现接口呢?

编译,但不工作:

IList<int> myList = new int[] { 1, 2, 4 };
myList.Add(5);

我们经常遇到这个问题,因为序列化器(WCF)将所有的list转换为数组,我们会得到运行时错误。

这是另一个让我困惑的问题:

static void PrintHowLong(DateTime a, DateTime b)
{
    TimeSpan span = a - b;
    Console.WriteLine(span.Seconds);        // WRONG!
    Console.WriteLine(span.TotalSeconds);   // RIGHT!
}

时间间隔。Seconds是时间跨度的秒部分(2分钟和0秒的秒值为0)。

时间间隔。TotalSeconds是以秒为单位测量的整个时间跨度(2分钟的总秒值为120)。

有时堆栈跟踪中的行号与源代码中的行号不匹配。这可能是因为为了优化而内联简单(单行)函数。对于使用日志进行调试的人来说,这是一个严重的混淆来源。

编辑:示例:有时你会在堆栈跟踪中看到一个空引用异常,它指向一行绝对不可能出现空引用异常的代码,就像一个简单的整数赋值。