簡體   English   中英

C#泛型方法類型約束到幾個類

[英]C# generic method type constraint to several classes

我有這樣的事情:

    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);得到一個錯誤var filteredQueryable = GetRowsAndFilter(predicate); “無法解決方法”。 它不知道如何選擇這些方法的正確版本。 我不知道該怎么辦。 應該可以將GetPageRows()中的通用算法與實際類型T以及不同版本的GetRowsAndFilter()中的每個T的特定不同查詢分開。

雖然您可以使用空接口來解決多個約束以指定一個約束,但這不會解決您的問題:無法正確解析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>() ),指定類型是其余要正確解析的驅動程序。

由於在C#中不可能進行多重繼承,因此除非Type1Type2Type3中的任何一個不是接口,否則不能這樣做。 如果Type1Type2Type3中不止一個不是接口,那么就不可能滿足約束條件。 此外,接口必須在類型約束的排序中排在最后。

你可能會說,等等,如果Type3 : Type2 : Type1 在你的情況下,我們仍然可以有一個滿足Type1但不滿足Type2Type3T 所以在這種情況下,我們從寫入Type1, Type2, Type3獲得的東西Type1, Type2, Type3因為它本身就等同於Type3

明確地指定這三種不同的類型是直覺錯誤的:你怎么知道,在編譯時安全地鍵入,你正在使用哪種類型? 定義它們全部派生的公共基類或它們都實現的接口,並將泛型參數類型約束到最小公分母。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM