LINQ是否有类似Match的语法

时间:2015-10-13 17:29:34

标签: c# linq pattern-matching strategy-pattern

这是一个我试图优雅地解决的案例。让我们说我有一个可枚举的(它可能是一个相当大的可枚举,我只想枚举一次)。如果序列中返回的对象符合操作的某些条件,我们还要说我有特定的操作要运行。

在函数式语言中,我可以设置一系列匹配,这些匹配将在找到匹配时执行。我想在C#中使用这样的东西。如果可能,使用LINQ。

我最接近的是使用策略模式和一个简单的规则引擎,它按顺序调用每个已注册的策略,直到找到匹配项。有更简单的方法吗?

我想做的事情是。

myEnum.Match((item)=>item.MatchesCondition, (item)=>ExecuteFunction(item))
  .Match((item)=>item.MatchesSomeOtherCondition, (item)=>ExecuteSomeOtherFunction(item));

3 个答案:

答案 0 :(得分:4)

您可以创建extension method dirname

Match

这将循环遍历public static class Extensions { public static IEnumerable<T> Match<T>(this IEnumerable<T> items, Func<T, bool> condition, Action<T> action) { foreach (T item in items) { if (condition(item)) { action(item) } else { yield return item; } } } } 中的每个项目:

  • 如果符合条件,请执行items
  • 否则,请通过iterator
  • 返回该项目

答案 1 :(得分:0)

您可以使用现有的LINQ功能,如下所示:

SomeList.Where(item => item.Equals(item));

如果您不想过滤完全匹配但是对于“包含”,您可以使用此表达式:

SomeList.Where(item => item.Contains(item));

答案 2 :(得分:0)

您可以创建一个包含条件和相关操作的词典,允许您继续循环一系列条件,直到找到匹配项,然后调用相关操作。

void Main()
{
    var collection = new List<string> { "One", "Two" };

    var dict = new Dictionary<Func<string, bool>, Action<string>>
    {
        { ConditionOne, ActionOne },
        { ConditionTwo, ActionTwo },
    };

    Match(collection, dict);
}

public void Match<T>(IEnumerable<T> collection, 
    Dictionary<Func<T, bool>, Action<T>> matchMap)
{
    var wasMatched = false;
    foreach (var item in collection)
    {
        if (wasMatched) break;

        foreach (var pair in matchMap)
        {
            if (wasMatched) break;

            if (pair.Key(item))
            {
                pair.Value(item);
                wasMatched = true;
            }   
        }
    }
}

public bool ConditionOne<T>(T item)
{
    return false;
}

public void ActionOne<T>(T item)
{
    Console.WriteLine(item);
}

public bool ConditionTwo<T>(T item)
{
    return true;
}

public void ActionTwo<T>(T item)
{
    Console.WriteLine(item);
}