在.NET 4.0中,什么是对的Equals值类型的默认实现? [英] In .NET 4.0, What is the default implementation of Equals for value types?

查看:183
本文介绍了在.NET 4.0中,什么是对的Equals值类型的默认实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两个文档页面似乎矛盾关于这个主题:

The two documentation pages seem to contradict on this topic:

  • ValueType.Equals Method says "The default implementation of the Equals method uses reflection to compare the corresponding fields of obj and this instance."
  • Object.Equals Method (Object) says "The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types."

因此​​,它是按位的平等或反射?

So is it bitwise equality or reflection?

我参加了一个一瞥值类型来源$ C ​​$ C,发现评论说:

I took a glimpse at the source code of ValueType and found a comment saying

//如果没有GC在引用这个对象,我们才能避免反射

// if there are no GC references in this object we can avoid reflection

//做一个快速的memcmp

// and do a fast memcmp

有人可以澄清GC引用意味着什么?我想这是具有引用类型的字段,但我不知道。

Can someone clarify what "GC reference" means? I guess it's a field having a reference type but I'm not sure.

如果我创建一个结构其中只有值类型字段,将它的实例始终比较快速的方式?

If I create a struct which only has value type fields, will the instances of it be always compared the fast way?

更新:文档为.NET 4.5已经显著改善:它是免费自提矛盾,现在给出了一个更好地了解如何将默认值类型相等检查工作

UPDATE: The documentation for.Net 4.5 has been significantly improved: it is free from the mentioned contradiction and now gives a better understanding how the default value type equality checking works.

推荐答案

值类型是特殊的。它这样做是:

ValueType is special. It does this:

  1. 如果obj的比较为null,则返回false。
  2. 如果在这一点,OBJ参数是不同的类型,则返回false。
  3. 它使用反射来调用等于每个实例字段的每个值,如果有的话这些字段不相等,则返回false。否则,它返回true,从未调用值类型base.Equals(是的Object.Equals)。

由于它使用反射来比较的字段,你应该总是重写等于任何值类型创建。反思是缓慢的。

Because it uses reflection to compare the fields, you should always override Equals on any ValueType you create. Reflection is slow.

当它是一个GCReference,或在结构,它是引用类型的字段,它采用每场反射做比较卷起。它必须这样做,因为结构实际上有一个指向堆上引用类型的位置。

When it's a "GCReference", or a field in the struct that is a reference type, it winds up using reflection on each field to do the comparison. It has to do this, because the struct actually has a pointer to the reference type's location on the heap.

如果有中引用在结构中没有提到的类型,并且它们是相同的时间,在字段保证是按照相同的顺序,并且是相同的大小在内存中,因此它可以只比较裸存储器。

If there is no reference type in referenced in the struct, and they are the same time, the fields are guaranteed to be in the same order, and be the same size in memory, so it can just compare the bare memory.

对于只有值类型的结构体的领域,即只有一个 INT 领域的结构,没有反射是一种比较期间完成。没有一个领域的引用在堆上东西,所以没有 GCReference 的GCHandle 。此外,这种结构的任何实例将具有相同的字段内存布局(有一些小的例外),所以在CLR团队可以执行直接存储器比较(memcmp),这是比其他选项快得多。

For a struct with only value types for fields, i.e. a struct with only one int field, no reflection is done during a comparison. None of the fields reference anything on the heap, so there is no GCReference or GCHandle. Furthermore, any instance of this structure will have the same in-memory layout of the fields (with a few minor exceptions), so the CLR team can do a direct memory comparison (memcmp), which is much faster than the other option.

所以,是的,如果你只有值类型在你的结构,它会做的更快memcmp,而不是反映比较,但你可能不希望这样做。请继续阅读。

So yes, if you only have value types in your structure, it will do the faster memcmp, instead of the reflection comparison, but you may not want to do that. Keep reading.

意味着你应该使用默认的等于的实施。事实上,不这样做。停下来。它做位的比较,这是的没有的总是准确的。那是什么,你说​​什么?让我告诉你:

This does not mean you should use the default equals implementation. In fact, do not do that. Stop it. It's doing bit comparisons, which are not always accurate. What is that you say? Let me show you:

private struct MyThing
{
    public float MyFloat;
}

private static void Main(string[] args)
{
    MyThing f, s;
    f.MyFloat = 0.0f;
    s.MyFloat = -0.0f;

    Console.WriteLine(f.Equals(s));  // prints False
    Console.WriteLine(0.0f == -0.0f); // prints True
}

的数量相等数学上,但它们不相等在其二进制重新presentation。所以,我要再次强调的是,不依赖ValueType.Equals的默认实现

这篇关于在.NET 4.0中,什么是对的Equals值类型的默认实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆