1

对于我正在尝试学习的内容,这可能是一个措辞不当的问题,所以我将解释我正在尝试做什么。我使用以下表达式创建了以下列表:

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) 是一个布尔函数。此外,我有三个不同的函数执行完全相同的操作,但在不同的列表中,这就是为什么我想学习如何将其简化为单个函数,只需传递列表和选择规则。

4

3 回答 3

3

只需定义一个谓词:一个接受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);
于 2013-01-29T13:38:55.033 回答
2

那么只需将 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();
于 2013-01-29T13:39:25.847 回答
1

您可以创建一个带有有效值列表的 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();

I've chose to use IEnumerable<object> instead of IEnumerable<string> to remove the .ToString() from each item this however does come with a sleight cost since you'll be boxing and unboxing any ValueTyped values. If it's on an identified performance critical path you should use IEnumerable<string> instead

于 2013-01-29T13:44:51.997 回答