c# Equal函數 and 運算符'==' (原發布 csdn 2017年10月15日 20:39:26)

一、==、!=、<、>、<= 和>= 運算符爲比較運算符(comparison operator)。C#語言規範5.0中文版中比較運算符的描述以下:

這裏寫圖片描述

二、通用類型系統

這裏寫圖片描述

三、值類型Equal函數 and 運算符'=='

3.一、常見類型 int、float、double、decimal等雖然繼承自ValueType,但其結構體內部重寫了Equal。

3.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.二、感興趣的可去Reference Source查看所有代碼。

3.1.三、測試代碼:

//T is int 、float、double、decimal、byte、char
            T a = 1234567890;//0.1234567890f、0.12345678九、1234567890M、(byte)十一、'a'
            T b = 1234567890;//0.1234567890f、0.12345678九、1234567890M、(byte)十一、'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.四、結論:對於簡單常見值類型 int、float、double、decimal等,Equal函數 and 運算符'==',若是其值相等,返回true;不然,返回false。

3.二、 結構體struct

3.2.一、 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) {
                        if (thatResult != null)
                            return false;
                    }
                    else
                    if (!thisResult.Equals(thatResult)) {
                        return false;
                    }
                }
     
                return true;
            }
     
            [System.Security.SecuritySafeCritical]  // auto-generated
            [ResourceExposure(ResourceScope.None)]
            [MethodImplAttribute(MethodImplOptions.InternalCall)]
            private static extern bool CanCompareBits(Object obj);
     
            [System.Security.SecuritySafeCritical]  // auto-generated
            [ResourceExposure(ResourceScope.None)]
            [MethodImplAttribute(MethodImplOptions.InternalCall)]
            private static extern bool FastEqualsCheck(Object a, Object b);         
        }

3.2.二、結構體(只有值類型,重寫Equal函數 and 運算符'==')

3.2.2.一、測試代碼:

struct Point
    {
        public double x;
        public double y;
        public double z;

        public Point(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }

        public override bool Equals(Object obj)
        {
            if (!(obj is Point))
            {
                return false;
            }

            if (((Point)obj).x == this.x)
            {
                return true;
            }

            return false;
        }
        public bool Equals(Point obj)
        {
            if (obj.x == this.x)
            {
                return true;
            }

            return false;
        }
        
        //運算符「Point.operator ==(Point, Point)」要求也要定義匹配的運算符「!=」
        public static bool operator ==(Point left, Point right)
        {
            return left.x == right.x;
        }

        public static bool operator !=(Point left, Point right)
        {
            return left.x != right.x;
        }
    }

    Point p1 = new Point(1, 2, 3);
    Point p2 = p1;
    
    p1.y = 100;
    Console.WriteLine(p1 == p2);//返回true
    Console.WriteLine(p1.Equals(p2)); // 返回true
    Console.WriteLine(p1.Equals((object)p2)); // 返回true

3.2.2.二、結論:此時程序執行咱們重寫的Equal函數 and 運算符'=='。

3.2.三、結構體(只有值類型,不重寫Equal函數 and 運算符'==')

3.2.3.一、測試代碼:

struct Point
    {
        public double x;
        public double y;
        public double z;

        public Point(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
    }

    Point p1 = new Point(1, 2, 3);
    Point p2 = p1;

    Console.WriteLine(p1 == p2);//編譯錯誤:運算符"=="沒法應用於"Point"和"Point"類型的操做數
    Console.WriteLine(p1.Equals(p2)); // 返回true
    Console.WriteLine(p1.Equals((object)p2)); // 返回true
    p1.y = 100;
    Console.WriteLine(p1.Equals(p2)); // 返回false
    Console.WriteLine(p1.Equals((object)p2)); // 返回false

3.2.3.二、程序執行時,CanCompareBits(this)返回true,代碼執行return FastEqualsCheck(thisObj, obj);

3.2.3.三、結論:程序判斷struct裏面全部字段的值,若是所有相等,返回true;不然,返回false。

3.2.四、複雜結構體(有值類型、引用類型,重寫Equal函數 and 運算符'==')

3.2.4.一、測試代碼:

public struct ValPoint
    {
        public double x;
        public double y;
        public double z;

        public ValPoint(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
        
        public static bool operator ==(ValPoint left, ValPoint right)
        {
            return left.x == right.x;
        }

        public static bool operator !=(ValPoint left, ValPoint right)
        {
            return left.x != right.x;
        }
    }

    public class RefPoint
    {
        public double x;
        public double y;
        public double z;

        public RefPoint(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
    }

    public struct ValLine
    {
        public ValPoint vPoint;       // 值類型成員

        public RefPoint rPoint;       // 引用類型成員

        public ValLine(ValPoint vPoint, RefPoint rPoint)
        {
            this.vPoint = vPoint;
            this.rPoint = rPoint;
        }

        public override bool Equals(Object obj)
        {
            if (!(obj is ValLine))
            {
                return false;
            }

            if (((ValLine)obj).vPoint == this.vPoint)
            {
                return true;
            }

            return false;
        }

        public bool Equals(ValLine obj)
        {
            if (obj.vPoint == this.vPoint)
            {
                return true;
            }

            return false;
        }

        public static bool operator ==(ValLine left, ValLine right)
        {
            return left.vPoint == right.vPoint;
        }

        public static bool operator !=(ValLine left, ValLine right)
        {
            return left.vPoint != right.vPoint;
        }
    }


    ValPoint vPoint = new ValPoint(1, 2, 3);
    ValPoint vPoint2 = new ValPoint(1, 2, 3);
    ValPoint vPoint3 = new ValPoint(10, 20, 30);
    RefPoint rPoint = new RefPoint(4, 5, 6);
    RefPoint rPoint2 = new RefPoint(7, 8, 9);

    ValLine p1 = new ValLine(vPoint, rPoint);
    ValLine p2 = p1;

    p2.vPoint = vPoint2;
    Console.WriteLine(p1 == p2); //返回true
    Console.WriteLine(p1.Equals(p2)); //返回true
    Console.WriteLine(p1.Equals((object)p2)); //返回true

    p2 = p1;
    p2.vPoint = vPoint3;
    Console.WriteLine(p1 == p2); //返回true
    Console.WriteLine(p1.Equals(p2)); //返回false
    Console.WriteLine(p1.Equals((object)p2)); //返回false

    p2 = p1;
    p2.rPoint = rPoint2;
    Console.WriteLine(p1 == p2); //返回true
    Console.WriteLine(p1.Equals(p2)); //返回true
    Console.WriteLine(p1.Equals((object)p2)); //返回true

3.2.4.二、結論:此時程序執行咱們重寫的Equal函數 and 運算符'=='。

3.2.五、複雜結構體(內部值類型、引用類型,不重寫Equal函數 and 運算符'==')

3.2.5.一、測試代碼:

public struct ValPoint
    {
        public double x;
        public double y;
        public double z;

        public ValPoint(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
    }

    public class RefPoint
    {
        public double x;
        public double y;
        public double z;

        public RefPoint(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
    }

    public struct ValLine
    {
        public ValPoint vPoint;       // 值類型成員

        public RefPoint rPoint;       // 引用類型成員

        public ValLine(ValPoint vPoint, RefPoint rPoint)
        {
            this.vPoint = vPoint;
            this.rPoint = rPoint;
        }
    }


    ValPoint vPoint = new ValPoint(1, 2, 3);
    ValPoint vPoint2 = new ValPoint(1, 2, 3);
    ValPoint vPoint3 = new ValPoint(10, 20, 30);
    RefPoint rPoint = new RefPoint(4, 5, 6);
    RefPoint rPoint2 = new RefPoint(7, 8, 9);

    ValLine p1 = new ValLine(vPoint, rPoint);
    ValLine p2 = p1;

    Console.WriteLine(p1 == p2);//編譯錯誤:運算符"=="沒法應用於"Point"和"Point"類型的操做數

    p2.vPoint = vPoint2;
    Console.WriteLine(p1.Equals(p2)); //返回true
    Console.WriteLine(p1.Equals((object)p2)); //返回true

    p2 = p1;
    p2.vPoint = vPoint3;
    Console.WriteLine(p1.Equals(p2)); //返回false
    Console.WriteLine(p1.Equals((object)p2)); //返回false
    
    p2 = p1;
    p2.rPoint = rPoint2;
    Console.WriteLine(p1.Equals(p2)); //返回false
    Console.WriteLine(p1.Equals((object)p2)); //返回false

3.2.5.二、程序執行時,CanCompareBits(this)返回false,代碼執行ValueType類Equal函數的下面語句

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) {
                        if (thatResult != null)
                            return false;
                    }
                    else
                    if (!thisResult.Equals(thatResult)) {
                        return false;
                    }
                }
     
                return true;

3.2.5.三、結論:程序判斷struct裏面全部字段,值類型就判斷值是否相等;引用類型就判斷是否引用相等。

四、引用類型Equal函數 and 運算符'=='

4.一、字符串string

4.1.一、C#語言規範5.0中文版中的字符串相等運算符介紹

這裏寫圖片描述

4.1.二、string的Equal函數和'=='重載運算符函數代碼

String
        {
            // Determines whether two strings match.
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            public override bool Equals(Object obj) {
                if (this == null)                        //this is necessary to guard against reverse-pinvokes and
                    throw new NullReferenceException();  //other callers who do not use the callvirt instruction
     
                String str = obj as String;
                if (str == null)
                    return false;
     
                if (Object.ReferenceEquals(this, obj))
                    return true;
     
                if (this.Length != str.Length)
                    return false;
     
                return EqualsHelper(this, str);
            }
     
            // Determines whether two strings match.
            [Pure]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            public bool Equals(String value) {
                if (this == null)                        //this is necessary to guard against reverse-pinvokes and
                    throw new NullReferenceException();  //other callers who do not use the callvirt instruction
     
                if (value == null)
                    return false;
     
                if (Object.ReferenceEquals(this, value))
                    return true;
                
                if (this.Length != value.Length)
                    return false;
     
                return EqualsHelper(this, value);
            }

            public static bool operator == (String a, String b) {
               return String.Equals(a, b);
            }

            // Determines whether two Strings match.
            [Pure]
            public static bool Equals(String a, String b) {
                if ((Object)a==(Object)b) {
                    return true;
                }
     
                if ((Object)a==null || (Object)b==null) {
                    return false;
                }
     
                if (a.Length != b.Length)
                    return false;
     
                return EqualsHelper(a, b);
            }

            [System.Security.SecuritySafeCritical]  // auto-generated
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            private unsafe static bool EqualsHelper(String strA, String strB)
            {
                Contract.Requires(strA != null);
                Contract.Requires(strB != null);
                Contract.Requires(strA.Length == strB.Length);
     
                int length = strA.Length;
     
                fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
                {
                    char* a = ap;
                    char* b = bp;
     
                    // unroll the loop
    #if AMD64
                    // for AMD64 bit platform we unroll by 12 and
                    // check 3 qword at a time. This is less code
                    // than the 32 bit case and is shorter
                    // pathlength
     
                    while (length >= 12)
                    {
                        if (*(long*)a     != *(long*)b) return false;
                        if (*(long*)(a+4) != *(long*)(b+4)) return false;
                        if (*(long*)(a+8) != *(long*)(b+8)) return false;
                        a += 12; b += 12; length -= 12;
                    }
    #else
                    while (length >= 10)
                    {
                        if (*(int*)a != *(int*)b) return false;
                        if (*(int*)(a+2) != *(int*)(b+2)) return false;
                        if (*(int*)(a+4) != *(int*)(b+4)) return false;
                        if (*(int*)(a+6) != *(int*)(b+6)) return false;
                        if (*(int*)(a+8) != *(int*)(b+8)) return false;
                        a += 10; b += 10; length -= 10;
                    }
    #endif
     
                    // This depends on the fact that the String objects are
                    // always zero terminated and that the terminating zero is not included
                    // in the length. For odd string sizes, the last compare will include
                    // the zero terminator.
                    while (length > 0) 
                    {
                        if (*(int*)a != *(int*)b) break;
                        a += 2; b += 2; length -= 2;
                    }
     
                    return (length <= 0);
                }
            }           

        }

4.1.三、Object.ReferenceEquals(this, value)若是this、value是同一個引用,返回true;不然,返回false。

{
                string a = "a1!";
                string b = "a1!";
                Console.WriteLine(Object.ReferenceEquals(a, b));//返回true,能夠判斷編譯器將a與b所指向的"a1!"優化成一個地方。
            }

            {
                string a = "Test";
                string b = string.Copy(a);
                Console.WriteLine(Object.ReferenceEquals(a, b));//返回false
            }

            {
                string a = "Test";
                string b = (string)a.Clone();
                Console.WriteLine(Object.ReferenceEquals(a, b));//返回true
            }

            {
                char[] ch = new char[] { 'a', 'A', '@' };
                string a = "aA@";
                string b = new string(ch);
                Console.WriteLine(Object.ReferenceEquals(a, b));//返回false
            }

4.1.四、學習EqualsHelper(String strA, String strB)函數以前,咱們先看一段代碼

unsafe
            {
                char[] firstCharA = "abc".ToCharArray();
                int length = firstCharA.Length;
                fixed (char* ap = firstCharA)
                {
                    for (int i = 0; i < length; i++)
                    {
                        Console.WriteLine(*(char*)(ap + i));
                    }
                }
            }

            unsafe
            {
                int[] firstCharA = new int[] { 1, 20, 300 };
                int length = firstCharA.Length;
                fixed (int* ap = firstCharA)
                {
                    for (int i = 0; i < length; i++)
                    {
                        Console.WriteLine(*(int*)(ap + i));
                    }
                }
            }

這裏寫圖片描述

4.1.五、修改後EqualsHelper(String strA, String strB)函數

private unsafe static bool EqualsHelper(String strA, String strB)
        {
            Contract.Requires(strA != null);
            Contract.Requires(strB != null);
            Contract.Requires(strA.Length == strB.Length);

            int length = strA.Length;

            char[] firstCharA = strA.ToCharArray();
            char[] firstCharB = strB.ToCharArray();

            fixed (char* ap = &firstCharA[0]) fixed (char* bp = &firstCharB[0])//因沒法使用m_firstChar,此處是我自行修改。ps:我的認爲m_firstChar是指字符串的第一字符,可是沒法證實。
            //fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
            {
                char* a = ap;
                char* b = bp;
                
                while (length >= 10)
                {
                    if (*(int*)a != *(int*)b) return false;
                    if (*(int*)(a + 2) != *(int*)(b + 2)) return false;
                    if (*(int*)(a + 4) != *(int*)(b + 4)) return false;
                    if (*(int*)(a + 6) != *(int*)(b + 6)) return false;
                    if (*(int*)(a + 8) != *(int*)(b + 8)) return false;
                    a += 10; b += 10; length -= 10;
                }

                // This depends on the fact that the String objects are
                // always zero terminated and that the terminating zero is not included
                // in the length. For odd string sizes, the last compare will include
                // the zero terminator.
                while (length > 0)
                {
                    if (*(int*)a != *(int*)b) break;
                    a += 2; b += 2; length -= 2;
                }

                return (length <= 0);
            }
        }

4.1.六、修改說明

一、fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)-> fixed (char* ap = &firstCharA[0]) fixed (char* bp = &firstCharB[0])
二、(*(int*)a->獲取的數據是兩個char值(低位ASCII*65536+高位ASCII)[低位在前,高位在後]。 [char兩個字節,範圍U+0000到U+FFFF]
三、(*(char*)a->獲取的數據是一個char值[見上面測試例子]

4.1.七、測試EqualsHelper(String strA, String strB)函數

{
                string a = "abcd";
                string b = "abcd";
                Console.WriteLine(EqualsHelper(a,b));//返回true
            }

            {
                string a = "Test";
                string b = string.Copy(a);
                Console.WriteLine(EqualsHelper(a, b));//返回true
            }

            {
                string a = "Test";
                string b = (string)a.Clone();
                Console.WriteLine(EqualsHelper(a, b));//返回true
            }

            {
                char[] ch = new char[] { 'a', 'A', '@' };
                string a = "aA@";
                string b = new string(ch);
                Console.WriteLine(EqualsHelper(a, b));//返回true
            }

4.1.八、結論:string類型 a == b、string.Equals(a, b)、a.Equals(b)、a.Equals((object)b),若是 a 的值與 b 的值相同,則爲 true;不然爲 false。

4.二、類class

4.2.一、C#語言規範5.0中文版中的引用類型相等運算符介紹

這裏寫圖片描述
這裏寫圖片描述

4.2.二、Object內部的Equals函數

Object
        {
            public virtual bool Equals(Object obj)
            {
                return RuntimeHelpers.Equals(this, obj);//沒法查到詳細代碼
            }
         
            public static bool Equals(Object objA, Object objB) 
            {
                if (objA==objB) {
                    return true;
                }
                if (objA==null || objB==null) {
                    return false;
                }
                return objA.Equals(objB);
            }
         
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            [System.Runtime.Versioning.NonVersionable]
            public static bool ReferenceEquals (Object objA, Object objB) {
                return objA == objB;
            }
        }

4.2.三、類(不重寫Equal函數 and 運算符'==')

public class RefPoint
    {
        public double x;
        public double y;
        public double z;

        public RefPoint(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
    }
    
            RefPoint p1 = new RefPoint(4, 5, 6);
            RefPoint p2 = p1;
            Console.WriteLine(p1.Equals(p2));//返回true
            Console.WriteLine(object.Equals(p1, p2));//返回true
            Console.WriteLine(object.ReferenceEquals(p1, p2));//返回true
            Console.WriteLine(p1 == p2);//返回true

            p2 = new RefPoint(4, 5, 6);//雖然值同樣,可是引用對象不同
            Console.WriteLine(p1.Equals(p2));//返回false
            Console.WriteLine(object.Equals(p1, p2));//返回false
            Console.WriteLine(object.ReferenceEquals(p1, p2));//返回false
            Console.WriteLine(p1 == p2);//返回false

4.2.四、類(重寫Equal函數 and 運算符'==')

public class RefPoint
    {
        public double x;
        public double y;
        public double z;

        public RefPoint(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }

        public override bool Equals(Object obj)
        {
            if (!(obj is RefPoint))
            {
                return false;
            }

            if (((RefPoint)obj).x == this.x)
            {
                return true;
            }

            return false;
        }

        public bool Equals(RefPoint obj)
        {
            if (obj.x == this.x)
            {
                return true;
            }

            return false;
        }

        public static bool operator ==(RefPoint left, RefPoint right)
        {
            return left.x == right.x;
        }

        public static bool operator !=(RefPoint left, RefPoint right)
        {
            return left.x != right.x;
        }
    }

            RefPoint p1 = new RefPoint(4, 5, 6);
            RefPoint p2 = p1;
            Console.WriteLine(p1.Equals(p2));//返回true
            Console.WriteLine(object.Equals(p1, p2));//返回true
            Console.WriteLine(object.ReferenceEquals(p1, p2));//返回true
            Console.WriteLine(p1 == p2);//返回true

            p2 = new RefPoint(4, 50, 60);
            Console.WriteLine(p1.Equals(p2));//返回true
            Console.WriteLine(object.Equals(p1, p2));//返回true
            Console.WriteLine(object.ReferenceEquals(p1, p2));//返回false
            Console.WriteLine(p1 == p2);//返回true

4.2.五、ReferenceEquals (Object objA, Object objB)返回objA == objB。若是objA、 objB引用同一個對象(只判斷是否引用同一個對象,即便咱們自行重載了'=='運算符,也沒用),返回true;不然,返回false。

五、總結

先介紹簡單值類型,再到結構體,字符串,類。把每一個類型Equal和'=='用法作個總結,加深本身記憶的同時,也但願能幫助到你。另:本文只表明本人觀點,若是有誤,還望告知。

六、參考

6.一、C#類型基礎

6.二、 C#語言規範5.0中文版

6.三、Reference Source

相關文章
相關標籤/搜索