1

我有这样的事情:

    public List<T> GetPageRows<T>(Expression<Func<T, bool>> predicate, List<ColumnSortOrder> sortOrder, int pageSize, int pageNo) where T : Type1, Type2, Type3
    {
        var filteredQueryable = GetRowsAndFilter(predicate);
        var orderedQueryable = GetOrderedQueryable(sortOrder, filteredQueryable);
        var pagedQueryable = orderedQueryable.Skip((pageNo - 1) * pageSize).Take(pageSize);
        return pagedQueryable.ToList();
    }

    private IQueryable<Type1> GetRowsAndFilter(Expression<Func<Type1, bool>> predicate)
    {
        return GetType1s(predicate);
    }

    private IQueryable<Type2> GetRowsAndFilter(Expression<Func<Type2, bool>> predicate)
    {
        return GetType2s(predicate);
    }

    private IQueryable<Type3> GetRowsAndFilter(Expression<Func<Type3, bool>> predicate)
    {
        return GetType3s(predicate);
    }

我希望通过制作 GetRowsAndFilter() 的非泛型类特定版本,然后将 GetPageRows() 的泛型类型参数限制为这三个类之一,编译器能够弄清楚要做什么。

不过where T : Type1, Type2, Type3好像是违法的。

我该如何解决这个问题?

这个想法是 GetPageRows() 中的算法是通用的,不依赖于我得到的特定类型的行。只有返回类型和谓词取决于 T。

编辑:我尝试限制它们的基本类型以及常见的空界面,但我仍然在var filteredQueryable = GetRowsAndFilter(predicate);. “无法解决方法”。它不知道如何选择这些方法的正确版本。我不知道该怎么办。应该可以将 GetPageRows() 中的通用算法与实际类型 T 以及不同版本的 GetRowsAndFilter() 中的每个 T 的特定不同查询分开。

4

3 回答 3

2

尽管您可以使用空接口来指定一个约束来绕过多个约束,但这并不能解决您的问题:无法GetRowsAndFilter正确解决。

在稍微弯曲代码之后,我想出了这个存根(我更改并删减了一些东西以使其编译,但您应该能够将相同的概念应用于您的代码):

    static void Main(string[] args)
    {
       var res = GetPageRows<Type1>(GetRowsAndFilter, t => true, null, 0, 0);
       var res2 = GetPageRows<Type2>(GetRowsAndFilter, t => true, null, 0, 0);

        Console.ReadLine();
    }

    public static List<T> GetPageRows<T>(Func<Expression<Func<T, bool>>, IEnumerable<T>> getRows, Expression<Func<T, bool>> predicate, List<int> sortOrder, int pageSize, int pageNo)
    {
        var filteredQueryable = getRows(predicate);
        return filteredQueryable.ToList();
    }

    private static IEnumerable<Type1> GetRowsAndFilter(Expression<Func<Type1, bool>> predicate)
    {
        return Enumerable.Empty<Type1>();
    }

    private static IEnumerable<Type2> GetRowsAndFilter(Expression<Func<Type2, bool>> predicate)
    {
        return Enumerable.Empty<Type2>();
    }

    private static IEnumerable<Type3> GetRowsAndFilter(Expression<Func<Type3, bool>> predicate)
    {
        return Enumerable.Empty<Type3>();
    }

您还需要提供要调用的方法,否则编译器无法解析它,因为它没有足够的关于 的类型信息T,通过提供方法并让它在方法签名中使用相同的泛型类型,编译器至少可以确保方法是相同的T。在调用方 ( GetPageRows<Type1>()) 中,指定类型是其余部分正确解析的驱动程序。

于 2013-05-30T13:41:37.153 回答
1

由于在 C# 中不可能进行多重继承,因此您不能这样做,除非最多有一个Type1,Type2并且Type3不是接口。如果多个Type1, Type2,Type3不是接口,则永远不可能满足约束。此外,接口必须在类型约束的排序中排在最后。

你可能会说,等等,万一Type3 : Type2 : Type1呢?在那种情况下,我们仍然可以有 a Tthat satifiesType1但不是Type2nor Type3。所以在这种情况下,我们从写作中没有任何收获,Type1, Type2, Type3因为它本身就等同于Type3它。

于 2013-05-30T13:44:15.710 回答
0

像这样明确地指定三种不同的类型在直觉上是错误的:你怎么知道,类型安全,在编译时,你正在使用哪种类型?定义一个它们都派生的公共基类或一个它们都实现的接口,并将泛型参数类型限制为最低公分母。

于 2013-05-30T13:41:30.463 回答