簡體   English   中英

具有非 Bool 結果的謂詞

[英]Predicate with non-Bool result

問題:具有非布爾結果的Predicate類型的格式未正確傳遞。

我正在創建一個基於List<>類型的新類型,主要是為了封裝在整個代碼中經常使用的命名。 希望定義一個自定義類型MyNewType ,其中包括一個項目列表,並保留大部分列表功能。 換句話說MyNewType.Count()得到MyNewType.Items.Count

新代碼采用以下形式:

public class MyNewType
{ 
    public List<MyListItems> Items { get; } 

    // Pass through List functions
    public void Add(MyListItems newItem) => this.Items.Add(newItem);
    public int Count() => this.Items.Count;

    public MyListItems FindAll(Predicate<MyListItems > predicate) => 
        new MyNewType(this.Items.FindAll(predicate));

    public T Sum<T>(Predicate<MyListItems,T> predicate) => this.Items.Sum(predicate);
}

FindAll中的謂詞使用編譯成功(待定,如果它工作正常),但謂詞為x => x.timex => x.ID形式的 Min/Max/Sum 和其他函數不編譯。

我沒有成功嘗試上面的Sum() function 的多次迭代。 理想情況下,表單與原始List.Sum() function 的表單相同; 聲明<type>可選。

INOP 形式:

public T Sum<T>(Predicate<MyListItems,T> predicate) => this.Items.Sum(predicate);

最后 - 可能是這個通用實現有缺陷,因為我需要重新聲明所有 List 函數作為傳遞,但我看不出 inheritance 是如何從 List 類型中得到一個不是List<type>形式的命名List<type>聲明使用屬性時。

嘗試過的版本,例如

public Sum(Predicate predicate) => this.Items.Sum(predicate);
public T Sum(Predicate<MyListItems,T> predicate) => this.Items.Sum(predicate);
public T Sum<T>(Predicate<MyListItems,T> predicate) => this.Items.Sum(predicate);
public DateTime Sum<DateTime>(Predicate<MyListItems,DateTime> predicate) => this.Items.Sum(predicate);

[更新] - 使用Func<>取得進展。 大多數電話都在工作。 剩下兩個問題:

  1. 如何使格式通用,因為目前是特定於類型的(雙精度)。
    public double Sum(Func<MyDataItem, double> predicate) => 
        this.Items.Sum(predicate);
  1. GroupBy鑄造問題 - 類似OrderBy的作品。
    public MyDataType GroupBy(Func<MyDataItem, DateTime> predicate)
    {
        List<MyDataItem> gdi = (List<MyDataItem>)Items.GroupBy(predicate);
        return this;
    }
Unable to cast object of type ( {...} sections removed)
'System.Linq.GroupedEnumerable`2[{...}.MyDataItem,System.DateTime]'
to type 'System.Collections.Generic.List`1[{...}.MyDataItem]'.

如果您能夠使用.Net 7 / C# 11,您可以使用新的通用數學支持來創建您自己的通用Sum / Min / Max (不幸的是,該庫還沒有包含公共通用 API,這是一個新功能)像這樣:

public static class IEnumerableExt {
    public static TNum Sum<T, TNum>(this IEnumerable<T> vals, Func<T, TNum> selFn) where TNum : INumber<TNum> {
        var result = TNum.Zero;
        foreach (var val in vals)
            checked {
                result += selFn(val);
            }
        return result;
    }

    public static TNum Max<T, TNum>(this IEnumerable<T> vals, Func<T, TNum> selFn) where TNum : INumber<TNum> {
        var e = vals.GetEnumerator();
        if (e.MoveNext()) {
            var result = selFn(e.Current);
            while (e.MoveNext()) {
                var curNum = selFn(e.Current);
                if (curNum > result)
                    result = curNum;
            }
            return result;
        }
        else
            throw new InvalidOperationException("No elements for Max");
    }
}

public class MyNewType {
    public List<MyListItems> Items { get; }

    public MyNewType(List<MyListItems> src) => Items = src;

    // Pass through List functions
    public void Add(MyListItems newItem) => this.Items.Add(newItem);
    public int Count() => this.Items.Count;

    public MyNewType FindAll(Predicate<MyListItems> predicate) =>
        new MyNewType(this.Items.FindAll(predicate));

    public T Sum<T>(Func<MyListItems, T> selFn) where T : INumber<T> => this.Items.Sum(selFn);
    public T Max<T>(Func<MyListItems, T> selFn) where T : INumber<T> => this.Items.Max(selFn);
}

暫無
暫無

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

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