Beispiel #1
0
            public static Func <T, T, int> BuildComparerFunc(SortCriteria sortCriteria)
            {
                string sortField = sortCriteria.SortField;

                if (!SortComparerFactory <T> .s_ComparerCache.TryGetValue(sortField, out Func <T, T, int> comparerFunc))
                {
                    comparerFunc = (x, y) =>
                    {
                        object?valueX = SortComparerReflectionHelper.FindPropertyGetMethod(x !.GetType(), sortField)?.Invoke(x, null);
                        object?valueY = SortComparerReflectionHelper.FindPropertyGetMethod(y !.GetType(), sortField)?.Invoke(y, null);

                        if (!TryEnsureValidReferences(valueX, valueY, out int referenceComparisonResult))
                        {
                            return(referenceComparisonResult);
                        }

                        Type targetType = SortComparerReflectionHelper.ResolveTargetType(valueX.GetType());
                        if (targetType == SortComparerReflectionHelper.ResolveTargetType(valueY.GetType()))
                        {
                            MethodInfo?compareToMethodInfo = SortComparerReflectionHelper.FindCompareToMethodInfo(targetType);
                            if (compareToMethodInfo != null)
                            {
                                return((int)compareToMethodInfo.Invoke(valueX, new object[] { valueY }));
                            }
                        }

                        return(Comparer <object> .Default.Compare(valueX, valueY));
                    };
                    SortComparerFactory <T> .s_ComparerCache.TryAdd(sortField, comparerFunc);
                }

                return(comparerFunc);
            }
            internal static Func <T, T, int> BuildPropertyComparer(Type typeX, Type typeY, string sortField)
            {
                MethodInfo?propertyX = SortComparerReflectionHelper.FindPropertyGetMethod(typeX, sortField);
                MethodInfo?propertyY = SortComparerReflectionHelper.FindPropertyGetMethod(typeY, sortField);

                if (propertyX == null && propertyY == null)
                {
                    return((x, y) => 0);
                }

                if (propertyX == null || propertyY == null)
                {
                    return(BuildOneSidedComparer((propertyX ?? propertyY) !, propertyX != null, sortField));
                }

                Type targetType = SortComparerReflectionHelper.ResolveTargetType(propertyX.ReturnType);

                if (targetType != SortComparerReflectionHelper.ResolveTargetType(propertyY.ReturnType))
                {
                    return(BuildDefaultComparer(propertyX, propertyY, sortField));
                }

                bool isEnum = targetType.IsEnum;

                if (isEnum)
                {
                    targetType = typeof(long);
                }

                MethodInfo?compareToMethodInfo = SortComparerReflectionHelper.FindCompareToMethodInfo(targetType);

                return(compareToMethodInfo == null
                                        ? BuildDefaultComparer(propertyX, propertyY, sortField)
                                        : !targetType.IsValueType
                                                ? BuildReferenceTypePropertyComparer(propertyX, propertyY, sortField, targetType, compareToMethodInfo)
                                                : BuildValueTypePropertyComparer(propertyX, propertyY, sortField, typeof(Nullable <>).MakeGenericType(targetType), targetType, compareToMethodInfo, isEnum));
            }