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


当前回答

可变集合中的值对象

struct Point { ... }
List<Point> mypoints = ...;

mypoints[i].x = 10;

没有效果。

mypoints[i]返回一个Point值对象的副本。c#允许您修改副本的字段。默默地什么也不做。


更新: 这似乎在c# 3.0中被修复了:

Cannot modify the return value of 'System.Collections.Generic.List<Foo>.this[int]' because it is not a variable

其他回答

类型。方法

我见过的咬了很多人的是Type.GetType(string)。他们想知道为什么它适用于自己程序集中的类型,以及一些类型,如System。字符串,而不是System.Windows.Forms.Form。答案是,它只能在当前程序集中和mscorlib中查找。


匿名方法

c# 2.0引入了匿名方法,导致了下面这种糟糕的情况:

using System;
using System.Threading;

class Test
{
    static void Main()
    {
        for (int i=0; i < 10; i++)
        {
            ThreadStart ts = delegate { Console.WriteLine(i); };
            new Thread(ts).Start();
        }
    }
}

打印出来的是什么?嗯,这完全取决于日程安排。它会输出10个数字,但它可能不会输出0 1 2 3 4 5 6 7 8 9这是你可能期望的。问题是被捕获的是变量i,而不是它在创建委托时的值。这可以用一个合适范围的额外局部变量轻松解决:

using System;
using System.Threading;

class Test
{
    static void Main()
    {
        for (int i=0; i < 10; i++)
        {
            int copy = i;
            ThreadStart ts = delegate { Console.WriteLine(copy); };
            new Thread(ts).Start();
        }
    }
}

迭代器块的延迟执行

这个“穷人单元测试”没有通过——为什么?

using System;
using System.Collections.Generic;
using System.Diagnostics;

class Test
{
    static IEnumerable<char> CapitalLetters(string input)
    {
        if (input == null)
        {
            throw new ArgumentNullException(input);
        }
        foreach (char c in input)
        {
            yield return char.ToUpper(c);
        }
    }
    
    static void Main()
    {
        // Test that null input is handled correctly
        try
        {
            CapitalLetters(null);
            Console.WriteLine("An exception should have been thrown!");
        }
        catch (ArgumentNullException)
        {
            // Expected
        }
    }
}

答案是,在迭代器的MoveNext()方法第一次被调用之前,CapitalLetters代码源中的代码不会被执行。

我的脑筋急转弯页面上还有一些奇怪的东西。

一些代码:

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

发生在我身上最糟糕的事情是webBrowser documentText问题:

Link

AllowNavigation解决方案工作在Windows窗体…

但在紧凑框架中,这种属性不存在……

...到目前为止,我找到的唯一解决办法是重建浏览器控件:

http://social.msdn.microsoft.com/Forums/it-IT/netfxcompact/thread/5637037f-96fa-48e7-8ddb-6d4b1e9d7db9

但是这样做,你需要处理手头的浏览器历史…: P

将容量传递给List<int>,而不是使用集合初始化式。

var thisOnePasses = new List<int> {2}; // collection initializer
var thisOneFails = new List<int> (2);  // oops, use capacity by mistake #gotcha#

thisOnePasses.Count.Should().Be(1);
thisOnePasses.First().Should().Be(2);

thisOneFails.Count.Should().Be(1);     // it's zero
thisOneFails.First().Should().Be(2);   // Sequence contains no elements...

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

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

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