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. publicoverrideboolEquals(Object obj) { if (!(obj is Double)) { returnfalse; } 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) { returntrue; } return IsNaN(temp) && IsNaN(m_value); }
[System.Runtime.Versioning.NonVersionable] publicstaticbooloperator ==(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 publicoverrideboolEquals(Object value) { if (valueis Decimal) { Decimal other = (Decimal)value; return FCallCompare(refthis, ref other) == 0; } returnfalse; }
//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'
// 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);
String { // Determines whether two strings match. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] publicoverrideboolEquals(Object obj) { if (this == null) //this is necessary to guard against reverse-pinvokes and thrownew NullReferenceException(); //other callers who do not use the callvirt instruction
String str = obj as String; if (str == null) returnfalse;
if (Object.ReferenceEquals(this, obj)) returntrue;
if (this.Length != str.Length) returnfalse;
return EqualsHelper(this, str); }
// Determines whether two strings match. [Pure] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] publicboolEquals(String value) { if (this == null) //this is necessary to guard against reverse-pinvokes and thrownew NullReferenceException(); //other callers who do not use the callvirt instruction
if (value == null) returnfalse;
if (Object.ReferenceEquals(this, value)) returntrue;
if (this.Length != value.Length) returnfalse;
return EqualsHelper(this, value); }
publicstaticbooloperator == (String a, String b) { return String.Equals(a, b); }
// Determines whether two Strings match. [Pure] publicstaticboolEquals(String a, String b) { if ((Object)a==(Object)b) { returntrue; }
if ((Object)a==null || (Object)b==null) { returnfalse; }
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) returnfalse; if (*(long*)(a+4) != *(long*)(b+4)) returnfalse; if (*(long*)(a+8) != *(long*)(b+8)) returnfalse; a += 12; b += 12; length -= 12; } #else while (length >= 10) { if (*(int*)a != *(int*)b) returnfalse; if (*(int*)(a+2) != *(int*)(b+2)) returnfalse; if (*(int*)(a+4) != *(int*)(b+4)) returnfalse; if (*(int*)(a+6) != *(int*)(b+6)) returnfalse; if (*(int*)(a+8) != *(int*)(b+8)) returnfalse; 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; }
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) returnfalse; if (*(int*)(a + 2) != *(int*)(b + 2)) returnfalse; if (*(int*)(a + 4) != *(int*)(b + 4)) returnfalse; if (*(int*)(a + 6) != *(int*)(b + 6)) returnfalse; if (*(int*)(a + 8) != *(int*)(b + 8)) returnfalse; 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); } }
修改说明
1 2 3
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值[见上面测试例子]