参见:http://topic.csdn.net/u/20090908/00/e64b8f60-0c91-44c0-a3dc-4387b8dfaa21.html---------------------------------Jeffrey Richter 的《Microsoft .NET 框架程序设计(修订版)》(李建忠译)第157-160页:
6.1.3 为值类型实现 Equals 方法第5章曾经说过,所有的值类型都继承自 System.ValueType。System.ValueType 重写了 System.Object 提供的 Equals 方法实现。System.ValueType.Equals 方法在内部首先使用反射机制(本书20章将予以探讨)来得到类型所有的实例字段(译注:尽管这样的 Equals 方法是在 ValueType 中实现的,但是反射机制本身可以保证它永远能够反射出实际类型--也就是继承自 ValueType 的值类型--中定义的所有字段,这里有一个“预知”的意思。当然这样的“预知”是有代价的),然后再比较它们是否相等。这种比较的过程效率很低,但却是一个所有的值类型都能继承的、相当不错的默认实现。至少,这样的做法意味着引用类型继承的 Equals 判断的是引用相等,而值类型继承的 Equals 判断的是值相等。对于没有显式重写 Equals 方法的值类型,ValueType 提供的实现将被继承。下面的代码展示了 System.ValueType.Equals 方法的内部实现。(代码略)虽然 ValueType 已经提供了一个相当好的 Equals 实现,并且也适用于我们定义的绝大多数值类型,但我们仍然应该提供自己的 Equals 实现。原因是我们自己的实现执行起来效率较高,并且可以避免额外的装箱操作。下面的代码展示了怎样为一个值类型实现 Equals 方法:(代码略)对于值类型,我们应该为它定义一个强类型版本的 Equals 方法,让其接受定义类型作为参数。这样做不仅可以提供类型安全,而且还可以避免额外的装箱操作。除此之外,我们也应该为 == 和 != 提供强类型的重载操作符。下面的代码演示了怎样判断两个值类型是否相等:(代码略)

解决方案 »

  1.   

    @空军,你真好...Compiler primitive types  Your compiler will provide implementations of the == and !=
    operators for types that it considers primitives. For example, the C# compiler knows how to
    compare Object, Boolean, Char, Int16, Uint16, Int32, Uint32, Int64, Uint64, Single,
    Double, Decimal, and so on for equality. In addition, these types provide implementations of
    Equals, so you can call this method as well as use operators.还是看原版好,应该翻译成:
    编译器为内置类型实现了==和!=运算现在又有了个新的问题,为什么Decimal也算?!Decimal应该排除在外吧,这个是重载过的,难道也这样?!
      

  2.   

    谁有同一作者的《框架设计(第2版) CLR Via C#》的相应章节,请贴上来,谢谢!
      

  3.   

    补上代码:
    另提示一下,代码也有可能过时
    同样说法也会改变,因为这些不是规范里的内容.public override bool Equals(Object obj)
    {
        if (obj == null) return false;    else
        {
            Type type = GetType();
            if (type != obj.GetType()) return false;
            FieldInfo[] fields = type.GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance);
            int posn;
            Object value1,value2;
            for (posn = 0; posn < fields.Length; ++posn)
            {
                value1 = fields[posn].GetValue(this);
                value2 = fields[posn].GetValue(obj);
                if (value1 == null)
                {
                    if (value2 != null) return false;
                }
                else if (value2 == null)
                {
                    return false;
                }
                else if (!value1.Equals(value2))
                {
                    return false;
                }
            }
            return true;
        }
    }
      

  4.   

    《Microsoft .NET 框架程序设计(修订版)》是基于 .net framevwork 1.1 版的,所以我想看看第2版是怎么论述的。看来应该去买一本《CLR Via C#》了。
      

  5.   

    @空军
    http://topic.csdn.net/u/20090904/21/639bdc71-16e8-48e8-9528-04c0b985dfdc.html
    还记得14楼关于struct类型hashcode的论述嘛.我验证了一下,发现也是错的.《Effective C#》第十章中关于结构类型hashcode的结论
    值类型自带的GetHashCode是以其第一个成员的GetHashCode值作为其的返回值。 public override int GetHashCode()
    {
        FieldInfo[] fields = GetType().GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance);
        int posn;
        Object value;
        for (posn = 0; posn < fields.Length; ++posn)
        {
            value = fields[posn].GetValue(this);
            if (value != null) return value.GetHashCode();
        }
        return GetType().GetHashCode();
    }现在这个说也法也过时了,不信大家自己做个验证,这里我就不上代码了.
      

  6.   

    基于以上担心,所以难以保证,下面的话就是对的:
    有的值类型都继承自 System.ValueType。System.ValueType 重写了 System.Object 提供的 Equals 方法实现。System.ValueType.Equals 方法在内部首先使用反射机制(本书20章将予以探讨)来得到类型所有的实例字段。的我猜测是:为了性能,也行有了新的做法.[1]不要盲从本书上的说教,要自己验证了才算数,更要注意一下论证的环境.(三段论)
    [2]可能.net的版本在变,情况同样会改变,除非是C#语言规范中认定的内容
      

  7.   


    第2版没有对应的章节,只在“5.5 对象相等性和身份标识”这一节中有这么一段:顺便提一句:System.ValueType(所有值类型的基类)重写了Object的Equals方法,并进行了正确的实现来执行相等性检查(而不是同一性检查)。在内部,ValueType的Equals是像这样实现的:
      1.如果obj参数为null,就返回false。
      2.如果this和obj参数引用不同类型的对象,就返回false。
      3.针对类型定义的每个实例字段,都将this对象的值与obj对象中的值进行比较。如果有字段不等,就返回false。
      4.返回true。ValueType的Equals方法不会调用Object的Equals方法。
      在内部,ValueType的Equals方法使用反射技术来完成上面的步骤3。由于CLR的反射机制较慢,所以在定义自己的值类型时,应该重写Equals方法,并提供自己的实现,以便在用类型的实例进行值相等性比较时提高性能。
      

  8.   

    这个是.net4.0里ValueType下的Equals
    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;
    }