簡體   English   中英

EqualityComparer 如何<T> .默認在內部工作?

[英]How does EqualityComparer<T>.Default works internally?

考慮 T = 字符串。

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

有什么建議..

反射器提供:

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>

EqualityComparer<T>.Default通過調用由System.Object定義但可能會或可能不會被T覆蓋的virtual方法Equals(object)GetHashCode()

請注意,由於方法是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

Tstring的情況下,類System.String重載了有問題的兩個方法並使用序數比較。 因此在這種情況下它應該等效於System.StringComparer.Ordinal 當然, string是一個sealed類,所以沒有其他類可以從string派生並以某種奇怪的方式覆蓋EqualsGetHashCode

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM