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


当前回答

重载==操作符和非类型化容器(数组列表、数据集等):

string my = "my ";
Debug.Assert(my+"string" == "my string"); //true

var a = new ArrayList();
a.Add(my+"string");
a.Add("my string");

// uses ==(object) instead of ==(string)
Debug.Assert(a[1] == "my string"); // true, due to interning magic
Debug.Assert(a[0] == "my string"); // false

解决方案?

总是使用字符串。当比较字符串类型时等于(a, b) 使用像List<string>这样的泛型来确保两个操作数都是字符串。

其他回答

前几天我看到了这个帖子,我觉得它很晦涩,对那些不知道的人来说很痛苦

int x = 0;
x = x++;
return x;

因为这将返回0,而不是大多数人期望的1

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

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

一些代码:

        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 -检查整数,直到找到“正确的”整数。

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

LinqToSQL和空集聚合

看这个问题。

如果你有一个LinqToSql查询,你正在运行一个聚合——如果你的结果集是空的,Linq不能计算出数据类型是什么,即使它已经声明了。

例:假设你有一个带有Amount字段的Claim表,它在LinqToSql中是十进制类型。

var sum = Claims.Where(c => c.ID < 0).Sum(c => c.Amount);

显然,没有任何声明的ID小于零,因此应该看到sum = null,对吧?错了!您会得到一个InvalidOperationException,因为Linq查询底层的SQL查询没有数据类型。你必须明确地告诉Linq它是一个小数!因此:

var sum = Claims.Where(c => c.ID < 0).Sum(c => (decimal?)c.Amount);

这真的很愚蠢,在我看来,这是微软的设计错误。

明白了!