Object.ReferenceEquals永远不会命中

时间:2011-10-26 19:21:16

标签: c#

任何人都可以告诉我为什么以下情况不会发生?

List<DateTime> timestamps = new List<DateTime>();
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");
    }
}

5 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:6)

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

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

DateTime是值类型

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

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

答案 2 :(得分:3)

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

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 Reference Type - Object Class C#的答案,他谈到拳击转换

答案 3 :(得分:1)

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

查看Object.ReferenceEquals

的MSDN条目

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

答案 4 :(得分:0)

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