欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-19 20:12:19
1、==、!=、、= 运算符为比较运算符(comparison operator)。C 语言规范5.0中文版中比较运算符的描述如下: 2、通用类型系统 3、值类型Equal函数 and 运算符'==' 3.1、常见类型 int、float、double、decimal等虽然继承自ValueType, ......

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

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

2、通用类型系统

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

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) {
                        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.2、结构体(只有值类型,重写equal函数 and 运算符'==')

3.2.2.1、测试代码:

    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.2、结论:此时程序执行我们重写的equal函数 and 运算符'=='。

3.2.3、结构体(只有值类型,不重写equal函数 and 运算符'==')

3.2.3.1、测试代码:

    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.2、程序执行时,cancomparebits(this)返回true,代码执行return fastequalscheck(thisobj, obj);

3.2.3.3、结论:程序判断struct里面所有字段的值,如果全部相等,返回true;否则,返回false。

3.2.4、复杂结构体(有值类型、引用类型,重写equal函数 and 运算符'==')

3.2.4.1、测试代码:

    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.2、结论:此时程序执行我们重写的equal函数 and 运算符'=='。

3.2.5、复杂结构体(内部值类型、引用类型,不重写equal函数 and 运算符'==')

3.2.5.1、测试代码:

    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.2、程序执行时,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.3、结论:程序判断struct里面所有字段,值类型就判断值是否相等;引用类型就判断是否引用相等。

4、引用类型equal函数 and 运算符'=='

4.1、字符串string

4.1.1、c#语言规范5.0中文版中的字符串相等运算符介绍

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

4.1.2、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.3、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.4、学习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));
                    }
                }
            }            

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

4.1.5、修改后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.6、修改说明

1、fixed (char* ap = &stra.m_firstchar) fixed (char* bp = &strb.m_firstchar)-> fixed (char* ap = &firstchara[0]) fixed (char* bp = &firstcharb[0])
2、(*(int*)a->获取的数据是两个char值(低位ascii*65536+高位ascii)[低位在前,高位在后]。 [char两个字节,范围u+0000到u+ffff]
3、(*(char*)a->获取的数据是一个char值[见上面测试例子]

4.1.7、测试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.8、结论:string类型 a == b、string.equals(a, b)、a.equals(b)、a.equals((object)b),如果 a 的值与 b 的值相同,则为 true;否则为 false。

4.2、类class

4.2.1、c#语言规范5.0中文版中的引用类型相等运算符介绍

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

4.2.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.3、类(不重写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.4、类(重写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.5、referenceequals (object obja, object objb)返回obja == objb。如果obja、 objb引用同一个对象(只判断是否引用同一个对象,即使我们自行重载了'=='运算符,也没用),返回true;否则,返回false。

5、总结

先介绍简单值类型,再到结构体,字符串,类。把每个类型equal和'=='用法做个总结,加深自己记忆的同时,也希望能帮助到你。另:本文只代表本人观点,如果有误,还望告知。

6、参考

6.1、c#类型基础

6.2、 c#语言规范5.0中文版

6.3、reference source