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); }
//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。這個是引用類型'==',放到下文介紹 */
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); }
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
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
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
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
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;
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); } } }
{ 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 }
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)); } } }
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); } }
一、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值[見上面測試例子]
{ 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 }
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; } }
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
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