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函数和 '=='重载符函数。

  1. Int32
  2. {
  3. public override bool Equals(Object obj) {
  4. if (!(obj is Int32)) {
  5. return false;
  6. }
  7. return m_value == ((Int32)obj).m_value;
  8. }
  9. [System.Runtime.Versioning.NonVersionable]
  10. public bool Equals(Int32 obj)
  11. {
  12. return m_value == obj;
  13. }
  14. }
  15. Double
  16. {
  17. // True if obj is another Double with the same value as the current instance. This is
  18. // a method of object equality, that only returns true if obj is also a double.
  19. public override bool Equals(Object obj) {
  20. if (!(obj is Double)) {
  21. return false;
  22. }
  23. double temp = ((Double)obj).m_value;
  24. // This code below is written this way for performance reasons i.e the != and == check is intentional.
  25. if (temp == m_value) {
  26. return true;
  27. }
  28. return IsNaN(temp) && IsNaN(m_value);
  29. }
  30. public bool Equals(Double obj)
  31. {
  32. if (obj == m_value) {
  33. return true;
  34. }
  35. return IsNaN(obj) && IsNaN(m_value);
  36. }
  37. [System.Runtime.Versioning.NonVersionable]
  38. public static bool operator ==(Double left, Double right) {
  39. return left == right;
  40. }
  41. }
  42. Single
  43. {
  44. public override bool Equals(Object obj) {
  45. if (!(obj is Single)) {
  46. return false;
  47. }
  48. float temp = ((Single)obj).m_value;
  49. if (temp == m_value) {
  50. return true;
  51. }
  52. return IsNaN(temp) && IsNaN(m_value);
  53. }
  54. public bool Equals(Single obj)
  55. {
  56. if (obj == m_value) {
  57. return true;
  58. }
  59. return IsNaN(obj) && IsNaN(m_value);
  60. }
  61. [System.Runtime.Versioning.NonVersionable]
  62. public static bool operator ==(Single left, Single right) {
  63. return left == right;
  64. }
  65. }
  66. Decimal
  67. {
  68. // Checks if this Decimal is equal to a given object. Returns true
  69. // if the given object is a boxed Decimal and its value is equal to the
  70. // value of this Decimal. Returns false otherwise.
  71. //
  72. [System.Security.SecuritySafeCritical] // auto-generated
  73. public override bool Equals(Object value) {
  74. if (value is Decimal) {
  75. Decimal other = (Decimal)value;
  76. return FCallCompare(ref this, ref other) == 0;
  77. }
  78. return false;
  79. }
  80. [System.Security.SecuritySafeCritical] // auto-generated
  81. public bool Equals(Decimal value)
  82. {
  83. return FCallCompare(ref this, ref value) == 0;
  84. }
  85. [System.Security.SecuritySafeCritical] // auto-generated
  86. public static bool operator ==(Decimal d1, Decimal d2) {
  87. return FCallCompare(ref d1, ref d2) == 0;
  88. }
  89. //暂时不知道此函数内部代码,如有知道还望告知。
  90. //根据测试结果,推测如果两个decimal数相等,返回0
  91. [System.Security.SecurityCritical] // auto-generated
  92. [ResourceExposure(ResourceScope.None)]
  93. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  94. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  95. private static extern int FCallCompare(ref Decimal d1, ref Decimal d2);
  96. }

3.1.2、感兴趣的可去Reference Source查看全部代码。

3.1.3、测试代码:

  1. //T is int 、float、double、decimal、byte、char
  2. T a = 1234567890;//0.1234567890f、0.123456789、1234567890M、(byte)11、'a'
  3. T b = 1234567890;//0.1234567890f、0.123456789、1234567890M、(byte)11、'a'
  4. Console.WriteLine(a == b);//返回true
  5. Console.WriteLine(a.Equals(b));//返回true
  6. Console.WriteLine(a.Equals((object)b));//返回true
  7. /*
  8. Console.WriteLine((object)a == b);//编译错误:运算符‘==’无法应用与‘object’和‘T’类型操作数
  9. Console.WriteLine(a == (object)b);//编译错误:运算符‘==’无法应用与‘object’和‘T’类型操作数
  10. //Console.WriteLine((object)a == (object)b);//返回false,下面解释为什么是false。这个是引用类型'==',放到下文介绍
  11. */

3.1.4、结论:对于简单常见值类型 int、float、double、decimal等,Equal函数 and 运算符'==',如果其值相等,返回true;否则,返回false。

3.2、 结构体struct

3.2.1、 ValueType内部的Equals函数

  1. ValueType
  2. {
  3. [System.Security.SecuritySafeCritical]
  4. public override bool Equals (Object obj) {
  5. BCLDebug.Perf(false, "ValueType::Equals is not fast. "+this.GetType().FullName+" should override Equals(Object)");
  6. if (null==obj) {
  7. return false;
  8. }
  9. RuntimeType thisType = (RuntimeType)this.GetType();
  10. RuntimeType thatType = (RuntimeType)obj.GetType();
  11. if (thatType!=thisType) {
  12. return false;
  13. }
  14. Object thisObj = (Object)this;
  15. Object thisResult, thatResult;
  16. // if there are no GC references in this object we can avoid reflection
  17. // and do a fast memcmp
  18. if (CanCompareBits(this))
  19. return FastEqualsCheck(thisObj, obj);
  20. FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  21. for (int i=0; i<thisFields.Length; i++) {
  22. thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
  23. thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
  24. if (thisResult == null) {
  25. if (thatResult != null)
  26. return false;
  27. }
  28. else
  29. if (!thisResult.Equals(thatResult)) {
  30. return false;
  31. }
  32. }
  33. return true;
  34. }
  35. [System.Security.SecuritySafeCritical] // auto-generated
  36. [ResourceExposure(ResourceScope.None)]
  37. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  38. private static extern bool CanCompareBits(Object obj);
  39. [System.Security.SecuritySafeCritical] // auto-generated
  40. [ResourceExposure(ResourceScope.None)]
  41. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  42. private static extern bool FastEqualsCheck(Object a, Object b);
  43. }

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

3.2.2.1、测试代码:

  1. struct Point
  2. {
  3. public double x;
  4. public double y;
  5. public double z;
  6. public Point(double X, double Y, double Z)
  7. {
  8. this.x = X;
  9. this.y = Y;
  10. this.z = Z;
  11. }
  12. public override bool Equals(Object obj)
  13. {
  14. if (!(obj is Point))
  15. {
  16. return false;
  17. }
  18. if (((Point)obj).x == this.x)
  19. {
  20. return true;
  21. }
  22. return false;
  23. }
  24. public bool Equals(Point obj)
  25. {
  26. if (obj.x == this.x)
  27. {
  28. return true;
  29. }
  30. return false;
  31. }
  32. //运算符“Point.operator ==(Point, Point)”要求也要定义匹配的运算符“!=”
  33. public static bool operator ==(Point left, Point right)
  34. {
  35. return left.x == right.x;
  36. }
  37. public static bool operator !=(Point left, Point right)
  38. {
  39. return left.x != right.x;
  40. }
  41. }
  42. Point p1 = new Point(1, 2, 3);
  43. Point p2 = p1;
  44. p1.y = 100;
  45. Console.WriteLine(p1 == p2);//返回true
  46. Console.WriteLine(p1.Equals(p2)); // 返回true
  47. Console.WriteLine(p1.Equals((object)p2)); // 返回true

3.2.2.2、结论:此时程序执行我们重写的Equal函数 and 运算符'=='。

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

3.2.3.1、测试代码:

  1. struct Point
  2. {
  3. public double x;
  4. public double y;
  5. public double z;
  6. public Point(double X, double Y, double Z)
  7. {
  8. this.x = X;
  9. this.y = Y;
  10. this.z = Z;
  11. }
  12. }
  13. Point p1 = new Point(1, 2, 3);
  14. Point p2 = p1;
  15. Console.WriteLine(p1 == p2);//编译错误:运算符"=="无法应用于"Point"和"Point"类型的操作数
  16. Console.WriteLine(p1.Equals(p2)); // 返回true
  17. Console.WriteLine(p1.Equals((object)p2)); // 返回true
  18. p1.y = 100;
  19. Console.WriteLine(p1.Equals(p2)); // 返回false
  20. 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、测试代码:

  1. public struct ValPoint
  2. {
  3. public double x;
  4. public double y;
  5. public double z;
  6. public ValPoint(double X, double Y, double Z)
  7. {
  8. this.x = X;
  9. this.y = Y;
  10. this.z = Z;
  11. }
  12. public static bool operator ==(ValPoint left, ValPoint right)
  13. {
  14. return left.x == right.x;
  15. }
  16. public static bool operator !=(ValPoint left, ValPoint right)
  17. {
  18. return left.x != right.x;
  19. }
  20. }
  21. public class RefPoint
  22. {
  23. public double x;
  24. public double y;
  25. public double z;
  26. public RefPoint(double X, double Y, double Z)
  27. {
  28. this.x = X;
  29. this.y = Y;
  30. this.z = Z;
  31. }
  32. }
  33. public struct ValLine
  34. {
  35. public ValPoint vPoint; // 值类型成员
  36. public RefPoint rPoint; // 引用类型成员
  37. public ValLine(ValPoint vPoint, RefPoint rPoint)
  38. {
  39. this.vPoint = vPoint;
  40. this.rPoint = rPoint;
  41. }
  42. public override bool Equals(Object obj)
  43. {
  44. if (!(obj is ValLine))
  45. {
  46. return false;
  47. }
  48. if (((ValLine)obj).vPoint == this.vPoint)
  49. {
  50. return true;
  51. }
  52. return false;
  53. }
  54. public bool Equals(ValLine obj)
  55. {
  56. if (obj.vPoint == this.vPoint)
  57. {
  58. return true;
  59. }
  60. return false;
  61. }
  62. public static bool operator ==(ValLine left, ValLine right)
  63. {
  64. return left.vPoint == right.vPoint;
  65. }
  66. public static bool operator !=(ValLine left, ValLine right)
  67. {
  68. return left.vPoint != right.vPoint;
  69. }
  70. }
  71. ValPoint vPoint = new ValPoint(1, 2, 3);
  72. ValPoint vPoint2 = new ValPoint(1, 2, 3);
  73. ValPoint vPoint3 = new ValPoint(10, 20, 30);
  74. RefPoint rPoint = new RefPoint(4, 5, 6);
  75. RefPoint rPoint2 = new RefPoint(7, 8, 9);
  76. ValLine p1 = new ValLine(vPoint, rPoint);
  77. ValLine p2 = p1;
  78. p2.vPoint = vPoint2;
  79. Console.WriteLine(p1 == p2); //返回true
  80. Console.WriteLine(p1.Equals(p2)); //返回true
  81. Console.WriteLine(p1.Equals((object)p2)); //返回true
  82. p2 = p1;
  83. p2.vPoint = vPoint3;
  84. Console.WriteLine(p1 == p2); //返回true
  85. Console.WriteLine(p1.Equals(p2)); //返回false
  86. Console.WriteLine(p1.Equals((object)p2)); //返回false
  87. p2 = p1;
  88. p2.rPoint = rPoint2;
  89. Console.WriteLine(p1 == p2); //返回true
  90. Console.WriteLine(p1.Equals(p2)); //返回true
  91. Console.WriteLine(p1.Equals((object)p2)); //返回true

3.2.4.2、结论:此时程序执行我们重写的Equal函数 and 运算符'=='。

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

3.2.5.1、测试代码:

  1. public struct ValPoint
  2. {
  3. public double x;
  4. public double y;
  5. public double z;
  6. public ValPoint(double X, double Y, double Z)
  7. {
  8. this.x = X;
  9. this.y = Y;
  10. this.z = Z;
  11. }
  12. }
  13. public class RefPoint
  14. {
  15. public double x;
  16. public double y;
  17. public double z;
  18. public RefPoint(double X, double Y, double Z)
  19. {
  20. this.x = X;
  21. this.y = Y;
  22. this.z = Z;
  23. }
  24. }
  25. public struct ValLine
  26. {
  27. public ValPoint vPoint; // 值类型成员
  28. public RefPoint rPoint; // 引用类型成员
  29. public ValLine(ValPoint vPoint, RefPoint rPoint)
  30. {
  31. this.vPoint = vPoint;
  32. this.rPoint = rPoint;
  33. }
  34. }
  35. ValPoint vPoint = new ValPoint(1, 2, 3);
  36. ValPoint vPoint2 = new ValPoint(1, 2, 3);
  37. ValPoint vPoint3 = new ValPoint(10, 20, 30);
  38. RefPoint rPoint = new RefPoint(4, 5, 6);
  39. RefPoint rPoint2 = new RefPoint(7, 8, 9);
  40. ValLine p1 = new ValLine(vPoint, rPoint);
  41. ValLine p2 = p1;
  42. Console.WriteLine(p1 == p2);//编译错误:运算符"=="无法应用于"Point"和"Point"类型的操作数
  43. p2.vPoint = vPoint2;
  44. Console.WriteLine(p1.Equals(p2)); //返回true
  45. Console.WriteLine(p1.Equals((object)p2)); //返回true
  46. p2 = p1;
  47. p2.vPoint = vPoint3;
  48. Console.WriteLine(p1.Equals(p2)); //返回false
  49. Console.WriteLine(p1.Equals((object)p2)); //返回false
  50. p2 = p1;
  51. p2.rPoint = rPoint2;
  52. Console.WriteLine(p1.Equals(p2)); //返回false
  53. Console.WriteLine(p1.Equals((object)p2)); //返回false

3.2.5.2、程序执行时,CanCompareBits(this)返回false,代码执行ValueType类Equal函数的下面语句

  1. FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  2. for (int i=0; i<thisFields.Length; i++) {
  3. thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
  4. thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
  5. if (thisResult == null) {
  6. if (thatResult != null)
  7. return false;
  8. }
  9. else
  10. if (!thisResult.Equals(thatResult)) {
  11. return false;
  12. }
  13. }
  14. return true;

3.2.5.3、结论:程序判断struct里面所有字段,值类型就判断值是否相等;引用类型就判断是否引用相等。

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

4.1、字符串string

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

4.1.2、string的Equal函数和'=='重载运算符函数代码

  1. String
  2. {
  3. // Determines whether two strings match.
  4. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  5. public override bool Equals(Object obj) {
  6. if (this == null) //this is necessary to guard against reverse-pinvokes and
  7. throw new NullReferenceException(); //other callers who do not use the callvirt instruction
  8. String str = obj as String;
  9. if (str == null)
  10. return false;
  11. if (Object.ReferenceEquals(this, obj))
  12. return true;
  13. if (this.Length != str.Length)
  14. return false;
  15. return EqualsHelper(this, str);
  16. }
  17. // Determines whether two strings match.
  18. [Pure]
  19. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  20. public bool Equals(String value) {
  21. if (this == null) //this is necessary to guard against reverse-pinvokes and
  22. throw new NullReferenceException(); //other callers who do not use the callvirt instruction
  23. if (value == null)
  24. return false;
  25. if (Object.ReferenceEquals(this, value))
  26. return true;
  27. if (this.Length != value.Length)
  28. return false;
  29. return EqualsHelper(this, value);
  30. }
  31. public static bool operator == (String a, String b) {
  32. return String.Equals(a, b);
  33. }
  34. // Determines whether two Strings match.
  35. [Pure]
  36. public static bool Equals(String a, String b) {
  37. if ((Object)a==(Object)b) {
  38. return true;
  39. }
  40. if ((Object)a==null || (Object)b==null) {
  41. return false;
  42. }
  43. if (a.Length != b.Length)
  44. return false;
  45. return EqualsHelper(a, b);
  46. }
  47. [System.Security.SecuritySafeCritical] // auto-generated
  48. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
  49. private unsafe static bool EqualsHelper(String strA, String strB)
  50. {
  51. Contract.Requires(strA != null);
  52. Contract.Requires(strB != null);
  53. Contract.Requires(strA.Length == strB.Length);
  54. int length = strA.Length;
  55. fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
  56. {
  57. char* a = ap;
  58. char* b = bp;
  59. // unroll the loop
  60. #if AMD64
  61. // for AMD64 bit platform we unroll by 12 and
  62. // check 3 qword at a time. This is less code
  63. // than the 32 bit case and is shorter
  64. // pathlength
  65. while (length >= 12)
  66. {
  67. if (*(long*)a != *(long*)b) return false;
  68. if (*(long*)(a+4) != *(long*)(b+4)) return false;
  69. if (*(long*)(a+8) != *(long*)(b+8)) return false;
  70. a += 12; b += 12; length -= 12;
  71. }
  72. #else
  73. while (length >= 10)
  74. {
  75. if (*(int*)a != *(int*)b) return false;
  76. if (*(int*)(a+2) != *(int*)(b+2)) return false;
  77. if (*(int*)(a+4) != *(int*)(b+4)) return false;
  78. if (*(int*)(a+6) != *(int*)(b+6)) return false;
  79. if (*(int*)(a+8) != *(int*)(b+8)) return false;
  80. a += 10; b += 10; length -= 10;
  81. }
  82. #endif
  83. // This depends on the fact that the String objects are
  84. // always zero terminated and that the terminating zero is not included
  85. // in the length. For odd string sizes, the last compare will include
  86. // the zero terminator.
  87. while (length > 0)
  88. {
  89. if (*(int*)a != *(int*)b) break;
  90. a += 2; b += 2; length -= 2;
  91. }
  92. return (length <= 0);
  93. }
  94. }
  95. }

4.1.3、Object.ReferenceEquals(this, value)如果this、value是同一个引用,返回true;否则,返回false。

  1. {
  2. string a = "a1!";
  3. string b = "a1!";
  4. Console.WriteLine(Object.ReferenceEquals(a, b));//返回true,可以判断编译器将a与b所指向的"a1!"优化成一个地方。
  5. }
  6. {
  7. string a = "Test";
  8. string b = string.Copy(a);
  9. Console.WriteLine(Object.ReferenceEquals(a, b));//返回false
  10. }
  11. {
  12. string a = "Test";
  13. string b = (string)a.Clone();
  14. Console.WriteLine(Object.ReferenceEquals(a, b));//返回true
  15. }
  16. {
  17. char[] ch = new char[] { 'a', 'A', '@' };
  18. string a = "aA@";
  19. string b = new string(ch);
  20. Console.WriteLine(Object.ReferenceEquals(a, b));//返回false
  21. }

4.1.4、学习EqualsHelper(String strA, String strB)函数之前,我们先看一段代码

  1. unsafe
  2. {
  3. char[] firstCharA = "abc".ToCharArray();
  4. int length = firstCharA.Length;
  5. fixed (char* ap = firstCharA)
  6. {
  7. for (int i = 0; i < length; i++)
  8. {
  9. Console.WriteLine(*(char*)(ap + i));
  10. }
  11. }
  12. }
  13. unsafe
  14. {
  15. int[] firstCharA = new int[] { 1, 20, 300 };
  16. int length = firstCharA.Length;
  17. fixed (int* ap = firstCharA)
  18. {
  19. for (int i = 0; i < length; i++)
  20. {
  21. Console.WriteLine(*(int*)(ap + i));
  22. }
  23. }
  24. }

4.1.5、修改后EqualsHelper(String strA, String strB)函数

  1. private unsafe static bool EqualsHelper(String strA, String strB)
  2. {
  3. Contract.Requires(strA != null);
  4. Contract.Requires(strB != null);
  5. Contract.Requires(strA.Length == strB.Length);
  6. int length = strA.Length;
  7. char[] firstCharA = strA.ToCharArray();
  8. char[] firstCharB = strB.ToCharArray();
  9. fixed (char* ap = &firstCharA[0]) fixed (char* bp = &firstCharB[0])//因无法使用m_firstChar,此处是我自行修改。ps:个人认为m_firstChar是指字符串的第一字符,但是无法证明。
  10. //fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
  11. {
  12. char* a = ap;
  13. char* b = bp;
  14. while (length >= 10)
  15. {
  16. if (*(int*)a != *(int*)b) return false;
  17. if (*(int*)(a + 2) != *(int*)(b + 2)) return false;
  18. if (*(int*)(a + 4) != *(int*)(b + 4)) return false;
  19. if (*(int*)(a + 6) != *(int*)(b + 6)) return false;
  20. if (*(int*)(a + 8) != *(int*)(b + 8)) return false;
  21. a += 10; b += 10; length -= 10;
  22. }
  23. // This depends on the fact that the String objects are
  24. // always zero terminated and that the terminating zero is not included
  25. // in the length. For odd string sizes, the last compare will include
  26. // the zero terminator.
  27. while (length > 0)
  28. {
  29. if (*(int*)a != *(int*)b) break;
  30. a += 2; b += 2; length -= 2;
  31. }
  32. return (length <= 0);
  33. }
  34. }

4.1.6、修改说明

  1. 1fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)-> fixed (char* ap = &firstCharA[0]) fixed (char* bp = &firstCharB[0])
  2. 2、(*(int*)a->获取的数据是两个char值(低位ASCII*65536+高位ASCII)[低位在前,高位在后]。 [char两个字节,范围U+0000U+FFFF]
  3. 3、(*(char*)a->获取的数据是一个char值[见上面测试例子]

4.1.7、测试EqualsHelper(String strA, String strB)函数

  1. {
  2. string a = "abcd";
  3. string b = "abcd";
  4. Console.WriteLine(EqualsHelper(a,b));//返回true
  5. }
  6. {
  7. string a = "Test";
  8. string b = string.Copy(a);
  9. Console.WriteLine(EqualsHelper(a, b));//返回true
  10. }
  11. {
  12. string a = "Test";
  13. string b = (string)a.Clone();
  14. Console.WriteLine(EqualsHelper(a, b));//返回true
  15. }
  16. {
  17. char[] ch = new char[] { 'a', 'A', '@' };
  18. string a = "aA@";
  19. string b = new string(ch);
  20. Console.WriteLine(EqualsHelper(a, b));//返回true
  21. }

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中文版中的引用类型相等运算符介绍



4.2.2、Object内部的Equals函数

  1. Object
  2. {
  3. public virtual bool Equals(Object obj)
  4. {
  5. return RuntimeHelpers.Equals(this, obj);//无法查到详细代码
  6. }
  7. public static bool Equals(Object objA, Object objB)
  8. {
  9. if (objA==objB) {
  10. return true;
  11. }
  12. if (objA==null || objB==null) {
  13. return false;
  14. }
  15. return objA.Equals(objB);
  16. }
  17. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  18. [System.Runtime.Versioning.NonVersionable]
  19. public static bool ReferenceEquals (Object objA, Object objB) {
  20. return objA == objB;
  21. }
  22. }

4.2.3、类(不重写Equal函数 and 运算符'==')

  1. public class RefPoint
  2. {
  3. public double x;
  4. public double y;
  5. public double z;
  6. public RefPoint(double X, double Y, double Z)
  7. {
  8. this.x = X;
  9. this.y = Y;
  10. this.z = Z;
  11. }
  12. }
  13. RefPoint p1 = new RefPoint(4, 5, 6);
  14. RefPoint p2 = p1;
  15. Console.WriteLine(p1.Equals(p2));//返回true
  16. Console.WriteLine(object.Equals(p1, p2));//返回true
  17. Console.WriteLine(object.ReferenceEquals(p1, p2));//返回true
  18. Console.WriteLine(p1 == p2);//返回true
  19. p2 = new RefPoint(4, 5, 6);//虽然值一样,但是引用对象不一样
  20. Console.WriteLine(p1.Equals(p2));//返回false
  21. Console.WriteLine(object.Equals(p1, p2));//返回false
  22. Console.WriteLine(object.ReferenceEquals(p1, p2));//返回false
  23. Console.WriteLine(p1 == p2);//返回false

4.2.4、类(重写Equal函数 and 运算符'==')

  1. public class RefPoint
  2. {
  3. public double x;
  4. public double y;
  5. public double z;
  6. public RefPoint(double X, double Y, double Z)
  7. {
  8. this.x = X;
  9. this.y = Y;
  10. this.z = Z;
  11. }
  12. public override bool Equals(Object obj)
  13. {
  14. if (!(obj is RefPoint))
  15. {
  16. return false;
  17. }
  18. if (((RefPoint)obj).x == this.x)
  19. {
  20. return true;
  21. }
  22. return false;
  23. }
  24. public bool Equals(RefPoint obj)
  25. {
  26. if (obj.x == this.x)
  27. {
  28. return true;
  29. }
  30. return false;
  31. }
  32. public static bool operator ==(RefPoint left, RefPoint right)
  33. {
  34. return left.x == right.x;
  35. }
  36. public static bool operator !=(RefPoint left, RefPoint right)
  37. {
  38. return left.x != right.x;
  39. }
  40. }
  41. RefPoint p1 = new RefPoint(4, 5, 6);
  42. RefPoint p2 = p1;
  43. Console.WriteLine(p1.Equals(p2));//返回true
  44. Console.WriteLine(object.Equals(p1, p2));//返回true
  45. Console.WriteLine(object.ReferenceEquals(p1, p2));//返回true
  46. Console.WriteLine(p1 == p2);//返回true
  47. p2 = new RefPoint(4, 50, 60);
  48. Console.WriteLine(p1.Equals(p2));//返回true
  49. Console.WriteLine(object.Equals(p1, p2));//返回true
  50. Console.WriteLine(object.ReferenceEquals(p1, p2));//返回false
  51. 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

c# Equal函数 and 运算符'==' (原发布 csdn 2017年10月15日 20:39:26)的更多相关文章

  1. 关于“关于C#装箱的疑问”帖子的个人看法 (原发布csdn 2017年10月07日 10:21:10)

    前言 昨天晚上闲着无事,就上csdn逛了一下,突然发现一个帖子很有意思,就点进去看了一下. 问题很精辟 int a = 1; object b=a; object c = b; c = 2; 为什么b ...

  2. datalab (原发布 csdn 2018年09月21日 20:42:54)

    首先声明datalab本人未完成,有4道题目没有做出来.本文博客记录下自己的解析,以便以后回忆.如果能帮助到你就更好了,如果觉得本文没啥技术含量,也望多多包涵. /* * bitAnd - x& ...

  3. [转载]Ubuntu17.04(Zesty Zapus)路线图发布:2017年4月13日发布

    Canonical今天公布了Ubuntu 17.04(Zesty Zapus)操作系统的发布路线图,该版本于今年10月24日上线启动,toolchain已经上传且首个daily ISO镜像已经生成.面 ...

  4. JavaScript图表FusionCharts免费在线公开课,由印度原厂技术工程师主讲,10月13日发车

    FusionCharts公开课达人还你做 轻松晋升图表大师 [开课时间]10月13日 14:30[主讲老师]印度原厂技术工程师[开课形式]网络在线公开课[活动费用]前50名免费 现在就可以报名哦  报 ...

  5. Visual Studio 2019 发布活动 - 2019 年 4 月 2 日

    Visual Studio 2019 发布活动 2019 年 4 月 2 日,星期二 | 上午 9:00 (PT) 围观: https://visualstudio.microsoft.com/zh- ...

  6. 10 月 30 日新款 Mac mini 有望与新款 iPad Pro 一起发布

    苹果最新款的 Mac mini 是在 2014 年 10 月推出的版本,到现在已经过了 4 年.分析师郭明錤和彭博社的 Mark Gurman 都表示苹果会在今年晚些时候发布新款 Mac mini. ...

  7. PyCharm 2017.2.3 版本在2017年9月7日发布,支持 Docker Compose

    PyCharm是由JetBrains打造的一款Python IDE.PyCharm具备用于一般IDE的功能,比如, 调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制 ...

  8. 12月15日下午Smarty模板函数

    1.{$var=...} 这是{assign}函数的简写版,你可以直接赋值给模版,也可以为数组元素赋值. <{$a = 10}><!--赋值语句--> <{$a}> ...

  9. WPF DataGrid显示MySQL查询信息,且可删除、修改、插入 (原发布 csdn 2018-10-13 20:07:28)

    1.入行好几年了,工作中使用数据库几率很小(传统行业).借着十一假期回家机会,学习下数据库. 2.初次了解数据库相关知识,如果本文有误,还望告知. 3.本文主要目的,记录下wpf界面显示数据库信息,且 ...

随机推荐

  1. PlayJava Day006

    今日所学: /* 2019.08.19开始学习,此为补档. */ 构造方法没有返回值(即return为空). this:实例(对象)的引用. JVM:①static方法区:存静态数据   ②栈区:引用 ...

  2. vi 上下左右变ABCD乱码解决方法

    CentOS echo "set nocompatible" >> ~/.vimrc source ~/.vimrc debian sudo apt-get remov ...

  3. Python的日志功能

    python自带的logging是日志处理模块,可以记录日志,并输出到控制台和文件等.日志分5个级别:DEBUG:调试信息,权重10INFO:一般信息,权重20WARNING:警告信息,权重30ERR ...

  4. MySQL通过SHOW TABLE STATUS查看库中所有表的具体信息

    有时候我们想看下指定库下所有表的使用情况,比如,查询表的Table大小,什么时候创建的,数据最近被更新的时间(即最近一笔insert/update/delete的时间).这些信息对我们进行库表维护很有 ...

  5. BayaiM__SQLLDR_linux_shell高级版

    BayaiM__SQLLDR_linux_shell高级版   备注:1.因公司在职,商业机密,顾IP地方加了"*"号,你可以任意写一个数字做IP做就好.2.不要瞎BB,哥自己写的 ...

  6. jira Licenses更新步骤

    有时候我们不想花钱使用jira,那么只有通过一个月以续期的方式来使用jira.下面提供下自己实测的方式 1.获取License Key 登录地址:https://my.atlassian.com 登录 ...

  7. Linux—yum使用详解

    yum配置 yum的配置文件在  /etc/yum.conf  参考:https://www.cnblogs.com/yhongji/p/9384780.html yum源配置 yum源文件在 /et ...

  8. 渗透测试学习 十七、 XSS跨站脚本漏洞详解

      一般用途:拿cookie进后台,将后台地址一起发送过来 特点:挖掘困难,绕过困难  大纲: XSS漏洞基础讲解 XSS漏洞发掘与绕过 XSS漏洞的综合利用 XSS漏洞基础讲解 XSS介绍: 跨站脚 ...

  9. 无法打开“Visual Studio Code”,因为Apple无法检查其是否包含恶意软件。”的问题解决

    解决方法: 1.系统偏好设置==> 安全性与隐私 ===> 在下方允许就可以了. 2.一劳永逸 但是注意安全性 打开terminal 命令行工具输入命令:sudo spctl --mast ...

  10. if, elif, else及if嵌套

    if 要判断的条件: 条件成立时,要做的事 ..... 注意:if语句以及缩进部分是看成一个完整的代码块,例如上述例子,不管age条件满不满足,最后一句打印欢迎光临始终会执行   else语法格式 i ...