1: public static bool IsDefault<T>(this T value)
2: {3: //...
4: }1. ==的問題
如果用==直接判斷(default(T) == value),編譯時(shí)會(huì)提示錯(cuò)誤:Error CS0019: 運(yùn)算符“==”無法應(yīng)用于“T”和“T”類型的操作數(shù) (CS0019)。
2. object.Equals的問題
object提供了一個(gè)靜態(tài)方法,可用于比較兩個(gè)對(duì)象是否相等:
1: public static bool Equals(object objA, object objB)
2: {3: if (objA == objB)
4: {5: return true;
6: }7: if (objA == null || objB == null)
8: {9: return false;
10: }11: return objA.Equals(objB);
12: } 但是該方法接收的是引用類型的實(shí)例,如果傳入的是值類型(譬如int、enum、struct等),則會(huì)對(duì)值類型進(jìn)行裝箱(boxing)。
3. EqualityComparer<T>.Default.Equals
最給力的方法,還是用EqualityComparer<T>.Default.Equals,
1: public static bool IsDefault<T>(this T value)
2: {3: return EqualityComparer<T>.Default.Equals(value, default(T));
4: }其實(shí)現(xiàn)了一個(gè)默認(rèn)的比較器,可以比較Byte、Nullable<T>、Enum、Object、以及實(shí)現(xiàn)了IEquatable<T>接口(譬如int、bool、自定義類型等)的所有類型,可以用ILSpy來查看該類型的具體實(shí)現(xiàn):
1: private static EqualityComparer<T> defaultComparer;
2: public static EqualityComparer<T> Default
3: {4: [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecuritySafeCritical]
5: get 6: { 7: EqualityComparer<T> equalityComparer = EqualityComparer<T>.defaultComparer;8: if (equalityComparer == null)
9: { 10: equalityComparer = EqualityComparer<T>.CreateComparer(); 11: EqualityComparer<T>.defaultComparer = equalityComparer; 12: }13: return equalityComparer;
14: } 15: } 16: [SecuritySafeCritical]17: private static EqualityComparer<T> CreateComparer()
18: {19: RuntimeType runtimeType = (RuntimeType)typeof(T);
20: if (runtimeType == typeof(byte))//其實(shí)byte也實(shí)現(xiàn)了IEquatable<Byte>,不知道為神馬要把byte單獨(dú)提出來???
21: {22: return (EqualityComparer<T>)new ByteEqualityComparer();
23: }24: if (typeof(IEquatable<T>).IsAssignableFrom(runtimeType))//如果類型實(shí)現(xiàn)了IEquatable<T>,則在運(yùn)行時(shí)構(gòu)造GenericEqualityComparer<T>,調(diào)用類型自身提供(重寫)的equals方法。
25: {26: return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), runtimeType);
27: }28: if (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(Nullable))
29: { 30: RuntimeType runtimeType2 = (RuntimeType)runtimeType.GetGenericArguments()[0];31: if (typeof(IEquatable).MakeGenericType(new Type[]
32: { 33: runtimeType2 34: }).IsAssignableFrom(runtimeType2)) 35: {36: return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer<int>), runtimeType2);
37: } 38: }39: if (runtimeType.IsEnum && Enum.GetUnderlyingType(runtimeType) == typeof(int))
40: {41: return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<int>), runtimeType);
42: }43: return new ObjectEqualityComparer<T>();
44: }
4. ILSpy比JustDecompile強(qiáng)大呀
4.1. ObjectEqualityComparer<T>.Equals方法的比較
4.2. EqualityComparer<T>.CreateComparer()方法:
各種杯具。。。



浙公網(wǎng)安備 33010602011771號(hào)