代码之家  ›  专栏  ›  技术社区  ›  Mr. Boy

基于属性选择的LINQ查询

  •  1
  • Mr. Boy  · 技术社区  · 14 年前
    IEnumerable<MyClass> objects = ...
    foreach(MyClass obj in objects)
    {
      if(obj.someProperty != null)
        SomeFunction(obj.someProperty);
    }
    

    我觉得我可以用lambda编写一个自鸣得意的LINQ版本,但我所有的C经验都是“经典的”,即更像Java,所有这些LINQ的东西让我困惑。

    6 回复  |  直到 7 年前
        1
  •  0
  •   Doctor Blue    14 年前

    您可以将if语句移到Linq的Where子句中:

    IEnumerable<MyClass> objects = ...
    foreach(MyClass obj in objects.Where(obj => obj.someProperty != null)
    {
        SomeFunction(obj.someProperty);
    }
    

    更进一步,你可以使用列表 ForEach

    IEnumerable<MyClass> objects = ...
    objects.Where(obj => obj.someProperty != null).ToList()
        .ForEach(obj => SomeFunction(obj.someProperty));
    

    不过,这使得代码稍微难以阅读。通常我坚持典型的 foreach ForEach公司 ,但这完全取决于你。

        2
  •  9
  •   Jon Skeet    14 年前

    foreach 回路:

    foreach (var value in objects.Select(x => x.someProperty)
                                 .Where(y => y != null))
    {
        SomeFunction(value);
    }
    

    或者如果需要查询表达式版本:

    var query = from obj in objects
                let value = obj.SomeProperty
                where value != null
                select value;
    foreach (var value in query)
    {
        SomeFunction(value);
    }
    

    请注意,我在筛选之前执行了选择,以避免不必要地调用属性两次。不是因为性能原因,而是我不喜欢冗余:)

    而你呢 使用 ToList() 打电话给我 ForEach() 回路,根据 Eric's explanation . 基本上 SomeFunction 必须招致一个副作用是有用的,而LINQ的设计考虑到了无副作用的功能。

        3
  •  1
  •   cRichter    14 年前
    objects.where(i => i.someProperty != null)
        .ToList()
        .ForEach(i=> SomeFunction(i.someProperty))
    
        4
  •  1
  •   Matthew Abbott    14 年前

        5
  •  1
  •   Richard    14 年前

    一种选择是使用书中概述的模式 Linq In Action 它使用扩展方法将ForEach运算符添加到IEnumerable<&燃气轮机;

    书中写道:

    public static void ForEach<T> (this IEnumerable<T> source, Action<T> func)
    {
       foreach (var item in source)
          func(item)
    }
    

    你可以这样用:

    (from foo in fooList 
      where foo.Name.Contains("bar")
      select foo)
      .ForEach(foo => Console.WriteLine(foo.Name));
    
        6
  •  1
  •   Guffa    14 年前

    LINQ用于创建结果,因此如果您使用它调用 SomeFunction 对于每个找到的项,您将使用代码的副作用来完成主要工作。这样的事情使得代码更难维护。

    foreach(MyClass obj in objects.Where(o => o.someProperty != null)) {
      SomeFunction(obj.someProperty);
    }