如何在 C# 中将多个函数作为约束参数传递
本文关键字:函数 约束 参数传递 | 更新日期: 2023-09-27 17:56:25
对于我正在尝试学习的内容来说,这可能是一个措辞糟糕的问题,所以我将解释我正在尝试做什么。我使用以下表达式创建了以下列表:
var showIndexes = from item in lItems
where WildcardString.IsMatch(item.RecordId.ToString(), filter) ||
WildcardString.IsMatch(item.Tokens.ToString(), filter) ||
WildcardString.IsMatch(string.Format("{0}:{1}", item.OwnerID.SystemName, item.OwnerID.Port.ToString()), filter) ||
WildcardString.IsMatch(item.ChildID.UserName, filter) ||
WildcardString.IsMatch(item.TypeOfLicense.ToString(), filter) ||
WildcardString.IsMatch(item.ExpiryTime.DateTime.ToLocalTime().ToString(), filter)
select item.RecordId.ToString();
我想把这个表达式放到一个函数中,并将"where"中使用的约束作为单个参数传递。我如何实现这一点?在使用文件属性时(当您选择不同的属性枚举时),我已经看到使用按位 OR 的类似功能,因此我相信应该可以编写自己的函数,该函数将一组委托作为"where"规则。
如果相关,WildcardString.IsMatch(string, string) 是一个布尔函数。此外,我有三个不同的函数执行完全相同的事情,但在不同的列表中,这就是为什么我想学习如何将其简化为单个函数,然后传递列表和选择规则。
只需定义一个谓词:一个接受item
并返回布尔值的函数。
假设item
属于类型 Record
并且filter
在范围内:
Func<Record, bool> predicate = r =>
WildCardString.IsMatch(r.RecordId.ToString(), filter) ||
WildCardString.IsMatch(...);
然后,您可以将predicate
视为一等值(存储它,将其作为参数传递等),IEnumerable<Record>
并使用
var filtered = enumerable.Where(predicate);
好吧,只需将 where 部分重构为一个函数:
public bool MyIsMatch(MyType item, String filter)
{
return
WildcardString.IsMatch(item.RecordId.ToString(), filter) ||
WildcardString.IsMatch(item.Tokens.ToString(), filter) ||
WildcardString.IsMatch(string.Format("{0}:{1}", item.OwnerID.SystemName, item.OwnerID.Port.ToString()), filter) ||
WildcardString.IsMatch(item.ChildID.UserName, filter) ||
WildcardString.IsMatch(item.TypeOfLicense.ToString(), filter) ||
WildcardString.IsMatch(item.ExpiryTime.DateTime.ToLocalTime().ToString(), filter);
}
然后称之为:
var showIndexes = from item in lItems where MyIsMatch(item, filter) select item.ToString();
您可以创建一个采用有效值列表的 Is.Match 版本
public static bool IsMatch(IEnumerable<object> values, filter) {
return values.All(v => IsMatch(v.ToString(),filter))
}
在您的情况下,您会像这样使用它
var values = new object[]{
item.RecordId,
item.Tokens,
string.Format("{0}:{1}", item.OwnerID.SystemName, item.OwnerID.Port),
item.ChildID.UserName
item.TypeOfLicense
item.ExpiryTime.DateTime};
var showIndexes = from item in lItems
where WildcardString.IsMatch(values,filter)
select item.RecordId.ToString();
我选择使用 IEnumerable<object>
而不是 IEnumerable<string>
从每个项目中删除.ToString()
,但这确实会带来诡计成本,因为您将对任何 ValueTyped 值进行装箱和取消装箱。如果它位于已识别的性能关键路径上,则应改用IEnumerable<string>