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


当前回答

Linq2SQL:接口成员的映射[…]不支持。

如果对实现接口的对象执行Linq2Sql查询,则会得到非常奇怪的行为。假设你有一个类MyClass,它实现了一个接口IHasDescription,这样:

public interface IHasDescription {
  string Description { get; set; }
}

public partial class MyClass : IHasDescription { }

(MyClass的另一半是一个Linq2Sql生成的类,包括属性Description。)

现在你写一些代码(这通常发生在泛型方法中):

public static T GetByDescription<T>(System.Data.Linq.Table<T> table, string desc) 
  where T : class, IHasDescription {
  return table.Where(t => t.Description == desc).FirstOrDefault();
}

编译正常-但你会得到一个运行时错误:

NotSupportedException: The mapping of interface member IHasDescription.Description is not supported.

现在该怎么办呢?好吧,这真的很明显:只需将==更改为.Equals(),这样:

return table.Where(t => t.Description.Equals(desc)).FirstOrDefault();

现在一切都好了!

在这里看到的。

其他回答

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

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

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

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

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

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

相当重要的环节:

关于值类型的真相

引用不是aAddress

堆栈是实现细节第1部分

堆栈是实现细节第2部分

一些代码:

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

抛出收到异常

一个让许多新开发人员困惑的问题是重新抛出异常语义。

我经常看到如下代码

catch(Exception e) 
{
   // Do stuff 
   throw e; 
}

问题是它会清除堆栈跟踪,并使诊断问题变得更加困难,因为您无法跟踪异常起源于何处。

正确的代码是不带参数的throw语句:

catch(Exception)
{
    throw;
}

或者将异常包装在另一个异常中,并使用内部异常获取原始堆栈跟踪:

catch(Exception e) 
{
   // Do stuff 
   throw new MySpecialException(e); 
}

相关对象和外键不同步

微软已经承认了这个漏洞。

我有一个类Thing,它有一个FK到Category。Category与Thing之间没有定义的关系,以免污染接口。

var thing = CreateThing(); // does stuff to create a thing
var category = GetCategoryByID(123); // loads the Category with ID 123
thing.Category = category;
Console.WriteLine("Category ID: {0}", thing.CategoryID); 

输出:

Category ID: 0

类似的:

var thing = CreateThing();
thing.CategoryID = 123;
Console.WriteLine("Category name: {0}", order.Category.Name);

抛出NullReferenceException。相关对象Category不加载ID为123的Category记录。

但是,在向DB提交更改之后,这些值将得到同步。但是在您访问DB之前,FK值和相关对象的功能实际上是独立的!

(有趣的是,同步FK值与相关对象的失败似乎只发生在没有定义子关系的情况下,即Category没有“Things”属性。但当你只是设置FK值时,“按需加载”永远不会起作用。)

明白了!