如何更新列表中的项目,通过Linq保持列表的其余部分完好无损

时间:2016-07-21 20:44:11

标签: c# linq updating

说我们有一个清单,

var dog = AllDogs.Where(d => d.Id == "2").FirstOrDefault();
if (dog != null) { dog.Name = "some value"; }

如果我想更新d4,请将其名称从willie更新为wolly。我想返回一份包含所有狗的列表,其中包含d4的更新。

我正在尝试这样的事情:

for loop

但是这只返回更新的项目,我想要包含更新项目的整个列表。

3 个答案:

答案 0 :(得分:1)

AllDogs将包含更新的对象,因此您需要做的就是将它作为公共属性(如果您从另一个类访问它)或私有类变量(如果您只是使用它来访问它)同一课)。

该行:

var dog = AllDogs.Where(d => d.Id == "2").FirstOrDefault();

返回对列表中对象的引用,以便在您更新它时:

if (dog != null) { dog.Name = "some value"; }

您正在列表中更新它。

答案 1 :(得分:1)

这是实现它的功能性方法。这会创建一个包含新狗的新列表。这适用于任何IEnumerable<Dog>

var dogs = AllDogs.Select(s => 
  new Dog() { Id = s.Id, Name = (s.Id == "2" ? "some value" : s.Name) });

这是一种在不创建任何新对象的情况下编辑列表的方法。这仅适用于List<Dog>

AllDogs.ForEach(f => f.Name = (f.Id == "2" ? "some value" : f.Name));

答案 2 :(得分:1)

您可以使用List.ConvertAll,它与Linq Select相同,然后使用ToList(或某些错综复杂的Aggregate)。 它将创建一个全新的List,其中包含与dog对象相同的引用以及在此过程中进行的修改:

// List.ConvertAll
var newAllDogs = allDogs.ConvertAll (dog => {
    if (dog.Id == 2)
        dog.Name = "some value";

    return dog;
});

// Linq version
var newAllDogs = allDogs.Select (dog => {
    if (dog.Id == 2)
        dog.Name = "some value";

    return dog;
}).ToList ();

但是做这种&#34;副作用突变&#34; (或者List.ForEach更多&#34;副作用&#34;)你应该几乎坚持经典&#34;命令式&#34;代码使用foreach循环或List.Find:

// foreach
foreach (var dog in allDogs)
    if (dog.Id == 2)
    {
        dog.Name = "some value";
        break;
    }

// List.Find
var theDog = allDogs.Find (dog => dog.Id == 2);
theDog?.Name = "some value"; // using C#6 null conditional operator

// without null conditional operator
if (theDog != null)
    theDog.Name = "some value";

// in both cases allDogs will contain the updated dog