How does EqualityComparer <T> .Default work inside?

Consider T = string.

I am wondering if it uses something like: typeof(EqualityComparer<T>).GetInterface("IEqualityComparer<T>");

Any suggestions..

+8
c #
source share
2 answers

Reflector provision:

 public static EqualityComparer<T> Default { get { EqualityComparer<T> defaultComparer = EqualityComparer<T>.defaultComparer; if (defaultComparer == null) { defaultComparer = EqualityComparer<T>.CreateComparer(); EqualityComparer<T>.defaultComparer = defaultComparer; } return defaultComparer; } } private static EqualityComparer<T> CreateComparer() { RuntimeType c = (RuntimeType) typeof(T); if (c == typeof(byte)) { return (EqualityComparer<T>) new ByteEqualityComparer(); } if (typeof(IEquatable<T>).IsAssignableFrom(c)) { return (EqualityComparer<T>) RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType) typeof(GenericEqualityComparer<int>), c); } if (c.IsGenericType && (c.GetGenericTypeDefinition() == typeof(Nullable<>))) { RuntimeType type2 = (RuntimeType) c.GetGenericArguments()[0]; if (typeof(IEquatable<>).MakeGenericType(new Type[] { type2 }).IsAssignableFrom(type2)) { return (EqualityComparer<T>) RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType) typeof(NullableEqualityComparer<int>), type2); } } if (c.IsEnum && (Enum.GetUnderlyingType(c) == typeof(int))) { return (EqualityComparer<T>) RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType) typeof(EnumEqualityComparer<int>), c); } return new ObjectEqualityComparer<T>(); } 

So, as you can see if T = string will return GenericEqualityComparer<string> .

+9
source share

EqualityComparer<T>.Default works by calling the virtual Equals(object) and GetHashCode() methods, which are defined by System.Object but may or may not be overridden by T

Note that since virtual methods, an implementation of a more derived class than T can be used. For example:

 EqualityComparer<object>.Default .Equals(new Uri("http://example.com/"), new Uri("http://example.com/")) 

will return true even if

 Object.ReferenceEquals(new Uri("http://example.com/"), new Uri("http://example.com/")) 

and

 (object)new Uri("http://example.com/") == (object)new Uri("http://example.com/") 

both return false .

In the case where T is a string , the System.String class overloads the two methods in question and uses ordinal comparison. Thus, in this case, it should be equivalent to System.StringComparer.Ordinal . And of course, string is a sealed class, so no other class can be obtained from string and override Equals and GetHashCode some strange way.

+2
source share

All Articles