Object.ReferenceEquals永远不会命中

谁能告诉我为什么以下情况不会发生?

List timestamps = new List(); timestamps.Add(DateTime.Parse("8/5/2011 4:34:43 AM")); timestamps.Add(DateTime.Parse("8/5/2011 4:35:43 AM")); foreach(DateTime x in timestamps) { if (Object.ReferenceEquals(x, timestamps.First())) { // Never hit Console.WriteLine("hello"); } } 

因为DateTime是一个值类型,不可变,所以即使值是引用也不相等。

你有意这样做吗? 价值比较:

 if (DateTime.Compare(x, timestamps.First()) == 0) { // Never hit Console.WriteLine("hello"); } 

传递值类型并按进行比较。 这就是为什么他们被称为“价值类型”。

参考类型通过引用传递和比较。 这就是为什么他们被称为“参考类型”。

DateTime是值类型

因此,您试图通过引用比较两个值。 那不行。 它总是假的。

你能解释为什么你会期待不同的东西吗?

我认为其他一些答案会遗漏一些东西。

object.ReferenceEquals(object,object)的情况下,任何值类型都被“装箱”到对象,并且这些(新)对象被传递。 考虑以下:

 DateTime d1 = DateTime.MinValue; DateTime d2 = d1; object ob1 = (object)d1; // boxed! object ob2 = ob1; // false - the values in d1 and d2 are BOXED to (new) different objects object.ReferenceEquals(d1, d2); // false - same as above, although I am not sure sure if a // VM implementation could re-use a BOXED object object.ReferenceEquals(d1, d1); // true - naturally - BOXED only once at "boxed!" (same object!) object.ReferenceEquals(ob1, ob2); 

快乐的编码。


相关:Marc在Value Type Vs中的答案参考类型 – 对象类C# ,他谈到了拳击转换

它们具有相同的值,但它们不是相同的参考。

查看Object.ReferenceEquals的MSDN条目

此外,即使你一直在比较同一个对象,你仍然不会通过比较引用来命中它,因为DateTime是一个结构,也就是说它是值类型。 根据定义, Value Types复制包含的值,而不是对象的引用(如Reference Types一样)。

对象首先在ReferenceEquals中复制,因为它们是值类型,因此引用永远不会相等。