默认比较器如何在C#中工作?

che*_*eft 7 c# linq sorting comparator

我正在使用OrderBy进行基于属性的排序,我找到了默认比较器文档,但它对我没有太多解释.如果一个对象没有实现System.IComparable<T>,它是如何生成的Comparer<T>

例如,我目前正在根据类型的属性值对对象列表进行排序object.它们是下面的数字类型,排序工作正常.C#/ Linq如何知道如何对对象进行排序?它是否会对基元进行一些非拳击?它是否进行了一些哈希检查?怎么会转化为大于或小于?

如果它们是一个更复杂的类型,它会失败并出现错误,或者OrderBy什么也不做,或者它甚至会以一种没有意义的方式排序?

Sco*_*ain 5

那么你可以检查参考源并亲自看看它的作用。

    public static Comparer<T> Default {
        get {
            Contract.Ensures(Contract.Result<Comparer<T>>() != null);

            Comparer<T> comparer = defaultComparer;
            if (comparer == null) {
                comparer = CreateComparer();
                defaultComparer = comparer;
            }
            return comparer;
        }
    }
    private static Comparer<T> CreateComparer() {
        RuntimeType t = (RuntimeType)typeof(T);

        // If T implements IComparable<T> return a GenericComparer<T>
#if FEATURE_LEGACYNETCF
        //(SNITP)
#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>();
    }
Run Code Online (Sandbox Code Playgroud)

所以它的作用是检查类型是否实现IComparable<T>,如果是,则使用该类型内置的比较器(数字类型的对象列表将遵循此分支)。然后,如果类型是 a,它会再次执行相同的检查Nullable<ICompareable<T>>。如果这也失败了,它会使用ObjectComparerwhich using Comparer.Default.

这是比较代码Comparer.Default

    public int Compare(Object a, Object b) {
        if (a == b) return 0;
        if (a == null) return -1;
        if (b == null) return 1;
        if (m_compareInfo != null) {
            String sa = a as String;
            String sb = b as String;
            if (sa != null && sb != null)
                return m_compareInfo.Compare(sa, sb);
        }

        IComparable ia = a as IComparable;
        if (ia != null)
            return ia.CompareTo(b);

        IComparable ib = b as IComparable;
        if (ib != null)
            return -ib.CompareTo(a);

        throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它检查 或a是否b实现IComparable,如果两者都没有,则不会抛出异常。