C# 如何为执行操作而加入,而不是选择任何内容
我需要将属性从一个列表复制到项目匹配的另一个列表,并且我可以很容易地将两个列表连接起来,如上面的示例所示,但是我认为另一个在我之后的开发人员会想“这到底是怎么回事?”因为我并没有按照预期的方式使用它。linq是否提供了一种更合适的方法来完成同样的事情C# 如何为执行操作而加入,而不是选择任何内容,c#,linq,C#,Linq,我需要将属性从一个列表复制到项目匹配的另一个列表,并且我可以很容易地将两个列表连接起来,如上面的示例所示,但是我认为另一个在我之后的开发人员会想“这到底是怎么回事?”因为我并没有按照预期的方式使用它。linq是否提供了一种更合适的方法来完成同样的事情 或者,如果我希望我的代码可读,我是否应该坚持使用循环而不是只使用一行?我个人更喜欢返回一个新列表的更实用的方法,但是如果你设置了这个方法来改变另一个列表,那么你可以做以下操作,这至少意味着副作用(通过ForEach): 但是,请记住,LINQ是一种
或者,如果我希望我的代码可读,我是否应该坚持使用循环而不是只使用一行?我个人更喜欢返回一个新列表的更实用的方法,但是如果你设置了这个方法来改变另一个列表,那么你可以做以下操作,这至少意味着副作用(通过
ForEach
):
但是,请记住,LINQ是一种无副作用的尝试…请注意,
并行枚举
和列表
提供了针对每个结果执行操作的方法,但这些是特定的枚举类型,可能不适合这种情况(边注:考虑通过这种特殊情况平行)
但是,默认的实现是执行循环,而不是使用传递给连接
或选择
的Func
,正如您所说,这可能会产生误导,并且需要一个未使用的返回值。将此表述为Justin Pihony在其回答中所做的,违反了“无副作用”的原则
这是您应该考虑使用匿名类型的确切形式,比如
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中没有为您完成,但您可以编写自己的ForEach
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;
}
publicstaticvoidforeach(此IEnumerable源代码,ActionAct)
{
foreach(T在源代码中)act(T);
}
使用同样的方法,偶尔也可以为IEnumerables编写自己的扩展方法(我特别喜欢使用UpdateCollectionTo
来更新ObservableCollection
中的项,而不只是替换引用…)为此,在参考源上浏览源coe以查找Join
,可能会有所帮助,虽然这不会损害性能,但在您陈述时阅读它确实会变得有趣。然而,它不一定会破坏任何东西,因此这是一种判断。无论您最终的解决方案如何,我都会对代码进行大量注释,以向任何未来的开发人员解释它的目的以及为什么这样做。Oh、 我绝对不会这样离开。我的观点是,如果我必须写注释来解释它,那么,只要有可能,最好是以一种有意义的方式重写代码,这样我就不需要留下注释。很酷,虽然一个列表中有很多项,而另一个列表中只有很少项,所以乍一看不确定,但这可能是正确的需要稍微调整一下。
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;
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T> act)
{
foreach(T t in source) act(t);
}