9

考虑 T = 字符串。

我很好奇它是否使用类似的东西:typeof(EqualityComparer<T>).GetInterface("IEqualityComparer<T>");

有什么建议么..

4

2 回答 2

9

由反射器提供:

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>();
}

所以你可以看到如果 T = string 它将返回GenericEqualityComparer<string>

于 2013-01-31T11:31:00.383 回答
2

EqualityComparer<T>.Default通过调用virtual方法工作Equals(object),这些方法GetHashCode()由.System.ObjectT

请注意,由于方法是,因此可以使用比可能使用virtual的更多派生类的实现。T例如:

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

会回来true的,即使

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

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

两者都返回false

在 where Tis的情况下string,该类System.String重载有问题的两个方法并使用序数比较。因此在这种情况下,它应该等价于System.StringComparer.Ordinal。当然string是一个sealed类,所以没有其他类可以以某种奇怪的方式派生和string覆盖。EqualsGetHashCode

于 2013-01-31T11:36:54.053 回答