[System.Security.SecuritySafeCritical] // auto-generated private static Comparer <T> CreateComparer() { RuntimeType t = (RuntimeType)typeof(T); // If T implements IComparable<T> return a GenericComparer<T> #if FEATURE_LEGACYNETCF // Pre-Apollo Windows Phone call the overload that sorts the keys, not values this achieves the same result if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) { if (t.ImplementInterface(typeof(IComparable <T>))) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), t)); } } else #endif if (typeof(IComparable <T>).IsAssignableFrom(t)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), t)); } // If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType(u).IsAssignableFrom(u)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), u)); } } // Otherwise return an ObjectComparer<T> return(new ObjectComparer <T>()); }
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>()); }
/// <summary> /// Creates the default <see cref="EqualityComparer{T}"/> for an enum type. /// </summary> /// <param name="enumType">The enum type to create the default equality comparer for.</param> private static object?TryCreateEnumEqualityComparer(RuntimeType enumType) { Debug.Assert(enumType != null); Debug.Assert(enumType.IsEnum); // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation // for how we cast the enum types to integral values in the comparer without boxing. TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing. switch (underlyingTypeCode) { case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.UInt16: return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <>), enumType)); } return(null); }
// // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen // saves the right instantiations // private static Comparer <T> CreateComparer() { object result = null; RuntimeType t = (RuntimeType)typeof(T); // If T implements IComparable<T> return a GenericComparer<T> if (typeof(IComparable <T>).IsAssignableFrom(t)) { result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), t); } else if (default(T) == null) { // If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType(u).IsAssignableFrom(u)) { result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), u); } } } else if (t.IsEnum) { // Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode // ends up doing this anyway, we end up avoiding an unnecessary P/Invoke // and virtual method call. TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing // Specialize differently for signed/unsigned types so we avoid problems with large numbers switch (underlyingTypeCode) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int32EnumComparer <int>), t); break; case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt32EnumComparer <uint>), t); break; // 64-bit enums: use UnsafeEnumCastLong case TypeCode.Int64: result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int64EnumComparer <long>), t); break; case TypeCode.UInt64: result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt64EnumComparer <ulong>), t); break; } } return(result != null ? (Comparer <T>)result : new ObjectComparer <T>()); // Fallback to ObjectComparer, which uses boxing }
[System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer <T> CreateComparer() { Contract.Ensures(Contract.Result <EqualityComparer <T> >() != null); RuntimeType t = (RuntimeType)typeof(T); // Specialize type byte for performance reasons if (t == typeof(byte)) { return((EqualityComparer <T>)(object)(new ByteEqualityComparer())); } // If T implements IEquatable<T> return a GenericEqualityComparer<T> if (typeof(IEquatable <T>).IsAssignableFrom(t)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer <int>), t)); } // If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IEquatable <>).MakeGenericType(u).IsAssignableFrom(u)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer <int>), u)); } } // If T is an int-based Enum, return an EnumEqualityComparer<T> // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation if (t.IsEnum && Enum.GetUnderlyingType(t) == typeof(int)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <int>), t)); } // Otherwise return an ObjectEqualityComparer<T> return(new ObjectEqualityComparer <T>()); }
[System.Security.SecuritySafeCritical] // auto-generated private static Comparer <T> CreateComparer() { object result = null; RuntimeType t = (RuntimeType)typeof(T); // If T implements IComparable<T> return a GenericComparer<T> if (typeof(IComparable <T>).IsAssignableFrom(t)) { result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), t); } else if (default(T) == null) { // If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType(u).IsAssignableFrom(u)) { result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), u); } } } return(result != null ? (Comparer <T>)result : new ObjectComparer <T>()); // Fallback to ObjectComparer, which uses boxing }
/// <summary> /// Creates the default <see cref="Comparer{T}"/>. /// </summary> /// <param name="type">The type to create the default comparer for.</param> /// <remarks> /// The logic in this method is replicated in vm/compile.cpp to ensure that NGen saves the right instantiations, /// and in vm/jitinterface.cpp so the jit can model the behavior of this method. /// </remarks> internal static object CreateDefaultComparer(Type type) { Debug.Assert(type != null && type is RuntimeType); object?result = null; var runtimeType = (RuntimeType)type; // If T implements IComparable<T> return a GenericComparer<T> if (typeof(IComparable <>).MakeGenericType(type).IsAssignableFrom(type)) { result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), runtimeType); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { // Nullable does not implement IComparable<T?> directly because that would add an extra interface call per comparison. var embeddedType = (RuntimeType)type.GetGenericArguments()[0]; result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), embeddedType); } // The comparer for enums is specialized to avoid boxing. else if (type.IsEnum) { result = TryCreateEnumComparer(runtimeType); } return(result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectComparer <object>), runtimeType)); }
/// <summary> /// Creates the default <see cref="EqualityComparer{T}"/> for an enum type. /// </summary> /// <param name="enumType">The enum type to create the default equality comparer for.</param> private static object TryCreateEnumEqualityComparer(RuntimeType enumType) { Debug.Assert(enumType != null); Debug.Assert(enumType.IsEnum); // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation // for how we cast the enum types to integral values in the comparer without boxing. TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing. // Note: We have different comparers for short and sbyte, since for those types GetHashCode does not simply return the value. // We need to preserve what they would return. switch (underlyingTypeCode) { case TypeCode.Int16: return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer <short>), enumType)); case TypeCode.SByte: return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer <sbyte>), enumType)); case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Byte: case TypeCode.UInt16: return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <int>), enumType)); case TypeCode.Int64: case TypeCode.UInt64: return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer <long>), enumType)); } return(null); }
/// <summary> /// Creates the default <see cref="Comparer{T}"/> for an enum type. /// </summary> /// <param name="enumType">The enum type to create the default comparer for.</param> private static object?TryCreateEnumComparer(RuntimeType enumType) { Debug.Assert(enumType != null); Debug.Assert(enumType.IsEnum); // Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode // ends up doing this anyway, we end up avoiding an unnecessary P/Invoke // and virtual method call. TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing. // Specialize differently for signed/unsigned types so we avoid problems with large numbers. switch (underlyingTypeCode) { case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumComparer <>), enumType)); } return(null); }
[System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer <T> CreateComparer() { Contract.Ensures(Contract.Result <EqualityComparer <T> >() != null); RuntimeType t = (RuntimeType)typeof(T);//获取泛型格式 // 用于性能原因的专门类型字节 if (t == typeof(byte)) { return((EqualityComparer <T>)(object)(new ByteEqualityComparer())); } // If T implements IEquatable<T> return a GenericEqualityComparer<T> // 如果T实现IEquatable<T>,则返回GenericEqualityComparer<T> if (typeof(IEquatable <T>).IsAssignableFrom(t)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer <int>), t)); } // If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U> // 如果T是一个实现了IEquatable<U>的Nullable<U>,将返回一个NullableEqualityComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IEquatable <>).MakeGenericType(u).IsAssignableFrom(u)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer <int>), u)); } } // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation if (t.IsEnum) { TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing // Note: We have different comparers for Short and SByte because for those types we need to make sure we call GetHashCode on the actual underlying type as the // implementation of GetHashCode is more complex than for the other types. switch (underlyingTypeCode) { case TypeCode.Int16: // short return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer <short>), t)); case TypeCode.SByte: return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer <sbyte>), t)); case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Byte: case TypeCode.UInt16: //ushort return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <int>), t)); case TypeCode.Int64: case TypeCode.UInt64: return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer <long>), t)); } } // Otherwise return an ObjectEqualityComparer<T> return(new ObjectEqualityComparer <T>()); }
private static IArraySortHelper <T> CreateArraySortHelper() { IArraySortHelper <T> defaultArraySortHelper; if (typeof(IComparable <T>).IsAssignableFrom(typeof(T))) { defaultArraySortHelper = (IArraySortHelper <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericArraySortHelper <string>), (RuntimeType)typeof(T)); } else { defaultArraySortHelper = new ArraySortHelper <T>(); } return(defaultArraySortHelper); }
/// <summary> /// Creates the default <see cref="Comparer{T}"/> for a nullable type. /// </summary> /// <param name="nullableType">The nullable type to create the default comparer for.</param> private static object TryCreateNullableComparer(RuntimeType nullableType) { Debug.Assert(nullableType != null); Debug.Assert(nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(Nullable <>)); var embeddedType = (RuntimeType)nullableType.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType(embeddedType).IsAssignableFrom(embeddedType)) { return(RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), embeddedType)); } return(null); }
private static EqualityComparer <T> CreateComparer() { RuntimeType runtimeType = (RuntimeType)typeof(T); if (runtimeType == typeof(byte)) { return((EqualityComparer <T>) new ByteEqualityComparer()); } if (typeof(IEquatable <T>).IsAssignableFrom(runtimeType)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer <int>), runtimeType)); } if (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType runtimeType2 = (RuntimeType)runtimeType.GetGenericArguments()[0]; if (typeof(IEquatable <>).MakeGenericType(new Type[] { runtimeType2 }).IsAssignableFrom(runtimeType2)) { return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer <int>), runtimeType2)); } } if (runtimeType.IsEnum) { switch (Type.GetTypeCode(Enum.GetUnderlyingType(runtimeType))) { case TypeCode.SByte: return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer <sbyte>), runtimeType)); case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <int>), runtimeType)); case TypeCode.Int16: return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer <short>), runtimeType)); case TypeCode.Int64: case TypeCode.UInt64: return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer <long>), runtimeType)); } } return(new ObjectEqualityComparer <T>()); }
private static Comparer <T> CreateComparer() { RuntimeType c = (RuntimeType)typeof(T); if (typeof(IComparable <T>).IsAssignableFrom(c)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), c)); } if (c.IsGenericType && (c.GetGenericTypeDefinition() == typeof(Nullable <>))) { RuntimeType type2 = (RuntimeType)c.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType(new Type[] { type2 }).IsAssignableFrom(type2)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), type2)); } } return(new ObjectComparer <T>()); }
private static Comparer <T> CreateComparer() { RuntimeType genericParameter1 = (RuntimeType)typeof(T); if (typeof(IComparable <T>).IsAssignableFrom((Type)genericParameter1)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), genericParameter1)); } if (genericParameter1.IsGenericType && genericParameter1.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType genericParameter2 = (RuntimeType)genericParameter1.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType((Type)genericParameter2).IsAssignableFrom((Type)genericParameter2)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), genericParameter2)); } } return((Comparer <T>) new ObjectComparer <T>()); }
[System.Security.SecuritySafeCritical] // auto-generated private static Comparer <T> CreateComparer() { RuntimeType t = (RuntimeType)typeof(T); // If T implements IComparable<T> return a GenericComparer<T> if (typeof(IComparable <T>).IsAssignableFrom(t)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer <int>), t)); } // If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IComparable <>).MakeGenericType(u).IsAssignableFrom(u)) { return((Comparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer <int>), u)); } } // Otherwise return an ObjectComparer<T> return(new ObjectComparer <T>()); }
[System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer <T> CreateComparer() { Contract.Ensures(Contract.Result <EqualityComparer <T> >() != null); object result = null; RuntimeType t = (RuntimeType)typeof(T); // Specialize type byte for performance reasons if (t == typeof(byte)) { result = new ByteEqualityComparer(); } // If T implements IEquatable<T> return a GenericEqualityComparer<T> else if (typeof(IEquatable <T>).IsAssignableFrom(t)) { result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer <int>), t); } else if (default(T) == null) // Reference type/Nullable { // If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IEquatable <>).MakeGenericType(u).IsAssignableFrom(u)) { result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer <int>), u); } } } // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation else if (t.IsEnum) { TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing // Note: We have different comparers for Short and SByte because for those types we need to make sure we call GetHashCode on the actual underlying type as the // implementation of GetHashCode is more complex than for the other types. switch (underlyingTypeCode) { case TypeCode.Int16: // short result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer <short>), t); break; case TypeCode.SByte: result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer <sbyte>), t); break; case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Byte: case TypeCode.UInt16: //ushort result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <int>), t); break; case TypeCode.Int64: case TypeCode.UInt64: result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer <long>), t); break; } } return(result != null ? (EqualityComparer <T>)result : new ObjectEqualityComparer <T>()); // Fallback to ObjectEqualityComparer, which uses boxing }
[System.Security.SecuritySafeCritical] // auto-generated private static EqualityComparer <T> CreateComparer() { Contract.Ensures(Contract.Result <EqualityComparer <T> >() != null); RuntimeType t = (RuntimeType)typeof(T); // Specialize type byte for performance reasons if (t == typeof(byte)) { return((EqualityComparer <T>)(object)(new ByteEqualityComparer())); } ///////////////////////////////////////////////// // KEEP THIS IN SYNC WITH THE DEVIRT CODE // IN METHOD-TO-IR.C ///////////////////////////////////////////////// #if MOBILE // Breaks .net serialization compatibility if (t == typeof(string)) { return((EqualityComparer <T>)(object) new InternalStringComparer()); } #endif // If T implements IEquatable<T> return a GenericEqualityComparer<T> if (typeof(IEquatable <T>).IsAssignableFrom(t)) { #if MONO return((EqualityComparer <T>)RuntimeType.CreateInstanceForAnotherGenericParameter(typeof(GenericEqualityComparer <>), t)); #else return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer <int>), t)); #endif } // If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U> if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>)) { RuntimeType u = (RuntimeType)t.GetGenericArguments()[0]; if (typeof(IEquatable <>).MakeGenericType(u).IsAssignableFrom(u)) { #if MONO return((EqualityComparer <T>)RuntimeType.CreateInstanceForAnotherGenericParameter(typeof(NullableEqualityComparer <>), u)); #else return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer <int>), u)); #endif } } // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation if (t.IsEnum) { TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t)); // Depending on the enum type, we need to special case the comparers so that we avoid boxing // Note: We have different comparers for Short and SByte because for those types we need to make sure we call GetHashCode on the actual underlying type as the // implementation of GetHashCode is more complex than for the other types. switch (underlyingTypeCode) { case TypeCode.Int16: // short #if MONO return((EqualityComparer <T>)RuntimeType.CreateInstanceForAnotherGenericParameter(typeof(ShortEnumEqualityComparer <>), t)); #else return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer <short>), t)); #endif case TypeCode.SByte: #if MONO return((EqualityComparer <T>)RuntimeType.CreateInstanceForAnotherGenericParameter(typeof(SByteEnumEqualityComparer <>), t)); #else return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer <sbyte>), t)); #endif case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Byte: case TypeCode.UInt16: //ushort #if MONO return((EqualityComparer <T>)RuntimeType.CreateInstanceForAnotherGenericParameter(typeof(EnumEqualityComparer <>), t)); #else return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer <int>), t)); #endif case TypeCode.Int64: case TypeCode.UInt64: #if MONO return((EqualityComparer <T>)RuntimeType.CreateInstanceForAnotherGenericParameter(typeof(LongEnumEqualityComparer <>), t)); #else return((EqualityComparer <T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer <long>), t)); #endif } } // Otherwise return an ObjectEqualityComparer<T> return(new ObjectEqualityComparer <T>()); }