C# - 值类型的Equals方法 - 为什么编译器使用反射? [英] C# - Value Type Equals method - why does the compiler use reflection?

查看:168
本文介绍了C# - 值类型的Equals方法 - 为什么编译器使用反射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚碰到的东西pretty怪我:当您使用equals()方法的值类型(如果这种方法还没有被重写,当然),你得到的东西的非常非常的慢 - 字段使用反射相比,一对一!如:

I just came across something pretty weird to me : when you use the Equals() method on a value type (and if this method has not been overriden, of course) you get something very very slow -- fields are compared one to one using reflection ! As in :

public struct MyStruct{
   int i;
}

   (...)

   MyStruct s, t;
   s.i = 0;
   t.i = 1;
   if ( s.Equals( t ))   /*  s.i will be compared to t.i via reflection here. */
      (...)

我的问题:为什么C#编译器不会产生一个简单的方法来比较值类型?喜欢的东西(在MYSTRUCT的定义):

My question : why does the C# compiler do not generate a simple method to compare value types ? Something like (in MyStruct's definition) :

   public override bool Equals( Object o ){
      if ( this.i == o.i )
         return true;
      else
         return false;
   }

编译器知道在编译时MYSTRUCT领域,为何等到运行时列举MYSTRUCT领域?

The compiler knows what are the fields of MyStruct at compile time, why does it wait until runtime to enumerate MyStruct fields ?

很奇怪我。

感谢:)

ADDED :对不起,我只是意识到这一点,当然,等于不是一种语言关键字,但运行时方法...编译器完全不知道这种方法的。因此,它使SENS这里使用反射。

ADDED : Sorry, I just realize that, of course, Equals is not a language keyword but a runtime method... The compiler is completely unaware of this method. So it make sens here to use reflection.

推荐答案

以下是从mscorlib程序反编译的方法ValueType.Equals:

The following is the decompiled ValueType.Equals method from mscorlib:

public override bool Equals(object obj)
{
    if (obj == null)
    {
        return false;
    }
    RuntimeType type = (RuntimeType) base.GetType();
    RuntimeType type2 = (RuntimeType) obj.GetType();
    if (type2 != type)
    {
        return false;
    }
    object a = this;
    if (CanCompareBits(this))
    {
        return FastEqualsCheck(a, obj);
    }
    FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        object obj3 = ((RtFieldInfo) fields[i]).InternalGetValue(a, false);
        object obj4 = ((RtFieldInfo) fields[i]).InternalGetValue(obj, false);
        if (obj3 == null)
        {
            if (obj4 != null)
            {
                return false;
            }
        }
        else if (!obj3.Equals(obj4))
        {
            return false;
        }
    }
    return true;
}

当可能的话,一个逐位比较,将在完成(注意CanCompareBits和FastEqualsCheck,这两者都定义为InternalCall该JIT将presumably此处注入适当$ C $角至于为什么它是那么慢,我不能告诉你。

When possible, a bit-wise comparison will be done (note the CanCompareBits and FastEqualsCheck, both of which are defined as InternalCall. The JIT would presumably inject the appropriate code here. As to why it is so slow, I couldn't tell you.

这篇关于C# - 值类型的Equals方法 - 为什么编译器使用反射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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