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


当前回答

只是发现了一个奇怪的问题,让我在调试中困了一段时间:

对于一个可为空的int,可以增加null值而不抛出异常,并且该值保持为空。

int? i = null;
i++; // I would have expected an exception but runs fine and stays as null

其他回答

海森堡表窗

如果你在做按需加载的事情,这会让你很难受,就像这样:

private MyClass _myObj;
public MyClass MyObj {
  get {
    if (_myObj == null)
      _myObj = CreateMyObj(); // some other code to create my object
    return _myObj;
  }
}

现在让我们假设你有一些代码在其他地方使用这个:

// blah
// blah
MyObj.DoStuff(); // Line 3
// blah

现在您需要调试CreateMyObj()方法。因此,您在上面的第3行上放置了一个断点,目的是进入代码。为了更好地度量,您还在上面的行中放置了一个断点,表示_myObj = CreateMyObj();,甚至在CreateMyObj()本身中也放置了一个断点。

代码在第3行碰到断点。你进入代码。您希望输入条件代码,因为_myObj显然是空的,对吗?嗯…所以…为什么它跳过条件直接返回_myObj?!将鼠标悬停在_myObj上…事实上,它确实有价值!怎么会这样?!

The answer is that your IDE caused it to get a value, because you have a "watch" window open - especially the "Autos" watch window, which displays the values of all variables/properties relevant to the current or previous line of execution. When you hit your breakpoint on Line 3, the watch window decided that you would be interested to know the value of MyObj - so behind the scenes, ignoring any of your breakpoints, it went and calculated the value of MyObj for you - including the call to CreateMyObj() that sets the value of _myObj!

这就是为什么我称其为海森堡观察窗口-你不能观察值而不影响它…:)

明白了!


编辑-我觉得@ChristianHayter的评论应该包含在主要答案中,因为它看起来是解决这个问题的有效方法。所以任何时候你有一个惰性加载的属性…

用[DebuggerBrowsable(DebuggerBrowsableState.Never)]或[DebuggerDisplay("<loaded on demand>")]装饰你的属性。——克里斯蒂安·海特

ASP。NET:

如果你正在使用Linq-To-SQL,你在数据上下文中调用SubmitChanges(),它会抛出一个异常(例如,重复的键或其他约束违反),当你调试时,有问题的对象值会保留在你的内存中,并且每次你随后调用SubmitChanges()时都会重新提交。

现在真正的问题是:即使您在IDE中按下“停止”按钮并重新启动,坏值仍将保留在内存中!我不明白为什么有人认为这是一个好主意-但小ASP。. NET图标弹出在您的系统托盘保持运行,它似乎保存您的对象缓存。如果你想冲洗你的内存空间,你必须右键单击该图标并强制关闭它!明白了!

MS SQL Server不能处理1753年以前的日期。值得注意的是,这与. net DateTime不同步。MinDate常数,也就是1/1/1。因此,如果你试图保存一个错误的日期(就像我最近在数据导入中遇到的那样),或者只是征服者威廉的出生日期,你就会遇到麻烦。没有内置的解决方案;如果你可能需要使用1753年之前的日期,你需要编写自己的变通方案。

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

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

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

我一直认为值类型总是在堆栈上,引用类型总是在堆上。

但事实并非如此。当我最近在SO上看到这个问题时(可以说回答是错误的),我才知道事实并非如此。

正如Jon Skeet的回答(引用Eric Lippert的博客文章),这是一个神话。

相当重要的环节:

关于值类型的真相

引用不是aAddress

堆栈是实现细节第1部分

堆栈是实现细节第2部分