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