使用Func的通用排序方法 代表

问题描述 投票:-2回答:1

我要做的是创建一个接受T类型列表的通用方法以及一些搜索选项(即排序方向和排序字段),然后根据搜索选项对给定列表进行排序。

我认为问题可能与我传递给OrderBy方法的Func委托的泛型返回类型有关,但我并不完全确定是诚实的。此刻相当难倒。这是我到目前为止所拥有的:

public static class TableGenerationHelper
{
    public static IList<T> CreateReportObject<T>(IList<T> items, ISearchOptions searchOptions) where T : new()
    {
        Type sortFieldType = typeof(T).GetProperty(searchOptions.SortField)?.GetType();

        MethodInfo createMethod = typeof(TableGenerationHelper).GetMethod("CreateSortedList");
        MethodInfo methodRef = createMethod?.MakeGenericMethod(typeof(T), sortFieldType);

        Object[] args = { items, searchOptions.SortField, searchOptions.SortDirection };

        results = (IList<T>)methodRef?.Invoke(null, args);

        return results;
    }

    public static IList<T> CreateSortedList<T, TH>(IList<T> items, String sortField, String sortDirection) where T : new()
    {
        Type type = typeof(T);
        PropertyInfo propInfo = type.GetProperty(sortField);

        Func<T, TH> orderByFunc = x => (TH)propInfo?.PropertyType.GetRuntimeProperty(sortField)?.GetValue(x, null);

        return LoadListOrderedByDirection(items, orderByFunc, sortDirection);
    }

    public static IList<T> LoadListOrderedByDirection<T, TH>(IList<T> items, Func<T, TH> keySelector, String sortDirection)
    {
        switch (sortDirection)
        {
            case "ASC":
                return items.OrderBy(keySelector).ToList();
            case "DESC":
                return items.OrderByDescending(keySelector).ToList();
            default:
                return items;
        }
    }
}

没有例外被抛出,但没有发生排序。原始列表按照传递的顺序返回。很感谢任何形式的帮助。

编辑

我很抱歉这里明显缺乏实际问题。老实说,我在发帖时没有意识到这一点。

感谢您对null运算符的建议。这给了我一个印象,即代码应该正常工作,当它真的应该抛出异常时。这使得调试非常令人沮丧,因为在执行代码时似乎没有任何问题。

正如StriplingWarrior在他的回答中提到的那样,我使用的是RuntimePropertyInfo而不是我的lambda表达式中的PropertyInfo

我下次发帖时一定会有一个实际的问题。

c# generics delegates
1个回答
0
投票

你正在吃一堆空值,这会让你错过一些你可能会看到异常的错误,而且Eric Lippert是正确的,你真的需要学习单步执行代码来调试它。

你在这里有几个错误。

  1. 您在PropertyType上使用propInfo,它为您提供属性返回的类型,而不是声明属性的对象类型。然后你要问具有给定名称的属性的类型(这对我来说没有多大意义,因为你已经拥有了首先调用GetProperty的PropertyInfo)。
  2. 您在GetType()的结果上使用GetProperty,它将始终返回运行时属性信息类的类型,而不是属性的实际类型。你想用PropertyType代替。

这似乎工作正常:

public static IList<T> CreateReportObject<T>(IList<T> items, ISearchOptions searchOptions) where T : new()
{
    Type sortFieldType = typeof(T).GetProperty(searchOptions.SortField).PropertyType;

    MethodInfo createMethod = typeof(TableGenerationHelper).GetMethod("CreateSortedList");
    MethodInfo methodRef = createMethod?.MakeGenericMethod(typeof(T), sortFieldType);

    Object[] args = { items, searchOptions.SortField, searchOptions.SortDirection };

    var results = (IList<T>)methodRef?.Invoke(null, args);

    return results;
}

public static IList<T> CreateSortedList<T, TH>(IList<T> items, String sortField, String sortDirection) where T : new()
{
    Type type = typeof(T);
    PropertyInfo propInfo = type.GetProperty(sortField);

    Func<T, TH> orderByFunc = x =>
    {
        return (TH)propInfo.GetValue(x, null);
    };

    return LoadListOrderedByDirection(items, orderByFunc, sortDirection);
}
© www.soinside.com 2019 - 2024. All rights reserved.