c# Equal函数 and 运算符'=='

1、==、!=、<、>、<= 和>= 运算符为比较运算符(comparison operator)。C#语言规范5.0中文版中比较运算符的描述如下:

这里写图片描述

2、通用类型系统

这里写图片描述

3、值类型Equal函数 and 运算符’==’

3.1、常见类型 int、float、double、decimal等虽然继承自ValueType,但其结构体内部重写了Equal。

3.1.1、 int,float,double,decimal内部的Equal函数和 ‘==’重载符函数。
        Int32
        {
            public override bool Equals(Object obj) {
                if (!(obj is Int32)) {
                    return false;
                }
                return m_value == ((Int32)obj).m_value;
            }

            [System.Runtime.Versioning.NonVersionable]
            public bool Equals(Int32 obj)
            {
                return m_value == obj;
            }           
        }

        Double
        {
            // True if obj is another Double with the same value as the current instance.  This is
            // a method of object equality, that only returns true if obj is also a double.
            public override bool Equals(Object obj) {
                if (!(obj is Double)) {
                    return false;
                }
                double temp = ((Double)obj).m_value;
                // This code below is written this way for performance reasons i.e the != and == check is intentional.
                if (temp == m_value) {
                    return true;
                }
                return IsNaN(temp) && IsNaN(m_value);
            }

            public bool Equals(Double obj)
            {
                if (obj == m_value) {
                    return true;
                }
                return IsNaN(obj) && IsNaN(m_value);
            }    

            [System.Runtime.Versioning.NonVersionable]
            public static bool operator ==(Double left, Double right) {
                return left == right;
            }           
        }

        Single
        {
            public override bool Equals(Object obj) {
                if (!(obj is Single)) {
                    return false;
                }
                float temp = ((Single)obj).m_value;
                if (temp == m_value) {
                    return true;
                }

                return IsNaN(temp) && IsNaN(m_value);
            }

            public bool Equals(Single obj)
            {
                if (obj == m_value) {
                    return true;
                }

                return IsNaN(obj) && IsNaN(m_value);
            }

             [System.Runtime.Versioning.NonVersionable]
            public static bool operator ==(Single left, Single right) {
                return left == right;
            }           
        }

        Decimal
        {
            // Checks if this Decimal is equal to a given object. Returns true
            // if the given object is a boxed Decimal and its value is equal to the
            // value of this Decimal. Returns false otherwise.
            //
            [System.Security.SecuritySafeCritical]  // auto-generated
            public override bool Equals(Object value) {
                if (value is Decimal) {
                    Decimal other = (Decimal)value;
                    return FCallCompare(ref this, ref other) == 0;
                }
                return false;
            }

            [System.Security.SecuritySafeCritical]  // auto-generated
            public bool Equals(Decimal value)
            {
                return FCallCompare(ref this, ref value) == 0;
            }   

            [System.Security.SecuritySafeCritical]  // auto-generated
            public static bool operator ==(Decimal d1, Decimal d2) {
                return FCallCompare(ref d1, ref d2) == 0;
            }

            //暂时不知道此函数内部代码,如有知道还望告知。
            //根据测试结果,推测如果两个decimal数相等,返回0
            [System.Security.SecurityCritical]  // auto-generated
            [ResourceExposure(ResourceScope.None)]
            [MethodImplAttribute(MethodImplOptions.InternalCall)]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            private static extern int FCallCompare(ref Decimal d1, ref Decimal d2);    

        }
3.1.2、感兴趣的可去Reference Source 查看全部代码。
3.1.3、测试代码:
            //T is int 、float、double、decimal、byte、char
            T a = 1234567890;//0.1234567890f、0.123456789、1234567890M、(byte)11、'a'
            T b = 1234567890;//0.1234567890f、0.123456789、1234567890M、(byte)11、'a'

            Console.WriteLine(a == b);//返回true
            Console.WriteLine(a.Equals(b));//返回true
            Console.WriteLine(a.Equals((object)b));//返回true

            /*
            Console.WriteLine((object)a == b);//编译错误:运算符‘==’无法应用与‘object’和‘T’类型操作数
            Console.WriteLine(a == (object)b);//编译错误:运算符‘==’无法应用与‘object’和‘T’类型操作数
            //Console.WriteLine((object)a == (object)b);//返回false,下面解释为什么是false。这个是引用类型'==',放到下文介绍
            */
3.1.4、结论:对于简单常见值类型 int、float、double、decimal等,Equal函数 and 运算符’==’,如果其值相等,返回true;否则,返回false。

3.2、 结构体struct

3.2.1、 ValueType内部的Equals函数
        ValueType
        {
            [System.Security.SecuritySafeCritical]
            public override bool Equals (Object obj) {
                BCLDebug.Perf(false, "ValueType::Equals is not fast.  "+this.GetType().FullName+" should override Equals(Object)");
                if (null==obj) {
                    return false;
                }
                RuntimeType thisType = (RuntimeType)this.GetType();
                RuntimeType thatType = (RuntimeType)obj.GetType();

                if (thatType!=thisType) {
                    return false;
                }

                Object thisObj = (Object)this;
                Object thisResult, thatResult;

                // if there are no GC references in this object we can avoid reflection 
                // and do a fast memcmp
                if (CanCompareBits(this))
                    return FastEqualsCheck(thisObj, obj);

                FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

                for (int i=0; i<thisFields.Length; i++) {
                    thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
                    thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);

                    if (thisResult == null) {
                        i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值