.NET4.0中值类型的Equals默认实现是什么?这两个文档页面似乎与这个主题相矛盾:Isitwiseequalityorreflection?我获取了ValueType并发现一条评论说//如果此对象中没有GC引用,我们可以避免反射//并快速执行memcmp有人可以澄清“GC引用”的含义吗?我猜这是一个引用类型的字段,但我不确定。如果我创建一个只有值类型字段的结构,它的实例是否总是与快速方式进行比较?更新:.Net4.5的文档已得到显着改进:它现在未提及的不一致之处可以更好地理解默认值类型相等性检查的工作原理。ValueType很特殊。它这样做:如果obj与null比较,则返回false。如果this和obj参数属于不同类型,则返回false。它使用反射在每个值的每个实例字段上调用??Equals,如果这些字段中的任何一个不相等,则返回false。否则返回true并且永远不会调用ValueTypesbase.Equals(即object.Equals)。因为它使用反射来比较字段,所以您应该始终覆盖您创建的任何ValueType上的Equals。反射很慢。当它是“GCReference”或引用类型的结构中的字段时,它会在每个字段上使用反射进行比较。它必须这样做,因为该结构实际??上有一个指向引用类型在堆上的位置的指针。如果结构中没有使用引用类型,并且它们是同一类型,则保证字段顺序相同,并且在内存中大小相同,因此它只能比较原始内存。对于只有字段值类型的结构,即只有一个int字段的结构,比较时不会发生反射。没有字段引用堆上的任何内容,因此没有GCReference或GCHandle。此外,此结构的任何实例都将具有相同的字段内存布局(有一些小例外),因此CLR团队可以进行直接内存比较(memcmp),这比其他选项快得多。所以,是的,如果你的结构中只有值类型,它会执行更快的memcmp而不是反射比较,但你可能不想这样做。继续阅读。这并不意味着您应该使用默认的equals实现。事实上,不要这样做。停止。它正在进行比较,但并不总是准确的。你说什么?让我向您演示:privatestructMyThing{publicfloatMyFloat;}privatestaticvoidMain(string[]args){MyThingf,s;f.MyFloat=0.0f;s.MyFloat=-0.0f;Console.WriteLine(f.Equals(s));//打印错误Console.WriteLine(0.0f==-0.0f);//打印True}这些数字在数学上是相等的,但它们的二进制表示不相等。所以,我会再次强调,不要依赖ValueType的默认实现。Equals不是这个领域的真正专家我会继续并提供我的想法:文档(据我所知)指出如果您的结构具有对象(引用类型)字段,则无法避免反射。因此,如果您有以下内容:publicstructSomeStruct{publicobjectObjectTest}ObjectTest不能在没有反射的情况下进行比较。所以会用到反射。这部分文字似乎说我是对的:“ValueType.Equals-Equals方法的默认实现使用反射将obj与此实例的相应字段进行比较。”的默认实现是什么?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
