web-dev-qa-db-ja.com

LinqのToList()。ForEach

私はLinqが初めてです。

このようにforeachステートメントに2つの値を設定したい

私の実際のコードはこれです

foreach (Employee emp in employees)
{
    foreach(Department dept in emp.Departments)
    {
        dept.SomeProperty = null;
    }
    collection.AddRange(emp.Departments);              
}

ほとんどリファクタリングは上記をこれに変えます

foreach (Employee emp in employees)
{
    emp.Departments.ToList().ForEach(u => u.SomeProperty = null))
    collection.AddRange(emp.Departments);              
}

しかし、私はこのようなものが欲しい

employees.ToList().Foreach(collection.AddRange(emp.Departments),
emp.Departments.ToList().ForEach(u => u.SomeProperty = null))
48
manav inder

ForEachをそのように使用しないでください。 Lippertの "foreach" vs "ForEach" を読む

自分(および世界)に対して残酷になりたい場合は、少なくとも無駄なListを作成しないでください。

employees.All(p => {
    collection.AddRange(p.Departments);
    p.Departments.All(u => { u.SomeProperty = null; return true; } );
    return true;
});

All式の結果は、破棄するbool値であることに注意してください(すべての要素を「循環」させるためだけに使用しています)

繰り返します。オブジェクトを変更するためにForEachを使用しないでください。 LINQは「機能的な」方法で使用する必要があります(新しいオブジェクトを作成できますが、古いオブジェクトを変更したり、副作用を作成したりすることはできません)。そして、あなたが書いているのは、2行のコードを得るためだけの無数のListを作成することです...

64
xanatos

ザナトスが言ったように、これはForEachの誤用です。

Linqを使用してこれを処理する場合は、次のようにします。

var departments = employees.SelectMany(x => x.Departments);
foreach (var item in departments)
{
    item.SomeProperty = null;
}
collection.AddRange(departments);

ただし、ループアプローチの方が読みやすいため、メンテナンスが容易です。

17
Charles Graham
employees.ToList().ForEach(
     emp=>
     {
          collection.AddRange(emp.Departments);
          emp.Departments.ToList().ForEach(u=>u.SomeProperty = null);
     });
11
artwl

これを試して:

foreach (var dept in employees.SelectMany(e => e.Departments))
{
   dept.SomeProperty = null;
   collection.Add(dept);
}
3
Ilian
employees.ToList().Foreach(u=> { u.SomeProperty = null; u.OtherProperty = null; });

->である各setステートメントの後にセミコロンを使用したことに注意してください。

u.SomeProperty = null;
u.OtherProperty = null;

これが間違いなくあなたの問題を解決することを願っています。

2
Saurabh