如何加入以执行操作,但不选择任何操作

时间:2015-01-29 22:57:04

标签: c# linq

listOne
    .Join(listTwo, 
          x => x.key, 
          y => y.key, 
          (x, y) => 
          { 
              y.SomeProperty = x.SomeProperty; 
              return 0; 
          });

我需要将一个属性从一个列表复制到另一个列表中的项目匹配,我可以轻松加入两个列表,如上面的示例所示,但我认为另一个开发人员会跟我说“哎呀?”因为我并没有按照预期的方式使用它。 linq是否提供了更合适的方法来完成同样的事情?

或者如果我希望我的代码可读,我应该坚持使用循环而不是尝试一行吗?

2 个答案:

答案 0 :(得分:0)

我个人更喜欢返回一个新列表的更实用的方法,但是如果你设置这个改变另一个列表,那么你可以做以下几个至少意味着副作用(通过ForEach):

val keyMatchedList= from x in listOne
                 join y in listTwo on x.key == y.key
                 select new {x.key, y.SomeProperty};

listTwo.ForEach(
  x=> x.SomeProperty = keyMatchedList.First(y=>y.Key == x.Key).SomeProperty);

但是,请记住,LINQ是一种无副作用的尝试......

答案 1 :(得分:0)

请注意,ParallelEnumerable<T>List<T>提供了针对每个结果执行Action<T>的方法,但这些是特定的可枚举类型,可能不适合这种情况(旁注:考虑并行)对于这种特殊情况,请.AsParallel()

但是,默认实现是执行循环而不是使用传递给FuncJoin的{​​{1}},如您所说,它可能会产生误导并且需要使用回报价值。用Justin Pihony的答案来表达这一点,这违反了“无副作用”的原则。

这是您应该考虑使用匿名类型的确切说明,如此

Select

更详细,但避免滥用方法,以某种方式可能会让某人不得不做双击。

另请注意,虽然在Linq中没有为您完成,但可以编写您自己的foreach(var pair in listOne .Join(listTwo, x => x.key, y => y.key, (x, y) => new { first = x, second = y})) { pair.first.SomeProperty = pair.second.SomeProperty; }

ForEach

使用同样的方法,建议偶尔为IEnumerables编写自己的扩展方法(我特别喜欢让public static void ForEach<T>(this IEnumerable<T> source, Action<T> act) { foreach(T t in source) act(t); } 更新UpdateCollecitonTo中的项目而不仅仅是替换引用。 ..)为此,在参考源

上浏览ObservableCollection的源coe可能会有所帮助