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


当前回答

内存泄漏,因为您没有取消关联事件。

这甚至让我认识的一些高级开发人员被发现了。

想象一个WPF表单,里面有很多东西,你在其中的某个地方订阅了一个事件。如果您不取消订阅,那么关闭和取消引用后,整个表单将保留在内存中。

我相信我看到的问题是在WPF表单中创建一个DispatchTimer并订阅Tick事件,如果你不对计时器做-=,你的表单泄漏内存!

在本例中,您的拆卸代码应该具有

timer.Tick -= TimerTickEventHandler;

这一点特别棘手,因为您在WPF表单中创建了DispatchTimer实例,所以您会认为它是一个由垃圾收集进程处理的内部引用……不幸的是,DispatchTimer在UI线程上使用了一个静态的订阅和服务请求的内部列表,所以引用是由静态类“拥有”的。

其他回答

一些代码:

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

内存泄漏,因为您没有取消关联事件。

这甚至让我认识的一些高级开发人员被发现了。

想象一个WPF表单,里面有很多东西,你在其中的某个地方订阅了一个事件。如果您不取消订阅,那么关闭和取消引用后,整个表单将保留在内存中。

我相信我看到的问题是在WPF表单中创建一个DispatchTimer并订阅Tick事件,如果你不对计时器做-=,你的表单泄漏内存!

在本例中,您的拆卸代码应该具有

timer.Tick -= TimerTickEventHandler;

这一点特别棘手,因为您在WPF表单中创建了DispatchTimer实例,所以您会认为它是一个由垃圾收集进程处理的内部引用……不幸的是,DispatchTimer在UI线程上使用了一个静态的订阅和服务请求的内部列表,所以引用是由静态类“拥有”的。

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

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

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

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

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

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

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>这样的泛型来确保两个操作数都是字符串。