[英]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.time
或x => 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<>
取得進展。 大多數電話都在工作。 剩下兩個問題:
public double Sum(Func<MyDataItem, double> predicate) =>
this.Items.Sum(predicate);
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.