C#从另一个列表更新列表

C#从另一个列表更新列表,c#,C#,我有两个列表。第一个,我们称之为ListA更像是一个完整的列表,第二个ListB是一个修改过的列表。现在我要做的是用ListB修改ListA。这可行吗?我该怎么做。这是我到目前为止所做的,但不起作用: var ListB = _repository.Get(m => m.Approved == true).ToList(); foreach (var x in ListB) { ListA.Where(d => d.Name == x.Name).First() = x; }

我有两个
列表
。第一个,我们称之为ListA更像是一个完整的列表,第二个ListB是一个修改过的列表。现在我要做的是用ListB修改ListA。这可行吗?我该怎么做。这是我到目前为止所做的,但不起作用:

var ListB = _repository.Get(m => m.Approved == true).ToList();
foreach (var x in ListB)
{
  ListA.Where(d => d.Name == x.Name).First() = x;
}

return ListA;
编辑:描述“修改”在我的情况下的含义的视觉演示

ListA
Id     Name      Age
1     John       14
2     Mark       15
3     Luke       13
4     Matthew    18

ListB
Id     Name      Age
2     Mark       0
4     Matthew    99
“修改”后,ListA应该如下所示:

ListA
Id     Name      Age
1     John       14
2     Mark       0
3     Luke       13
4     Matthew    99

我想只更新一个年龄。您也不需要使用

Where().First()
您只需要使用
First()

如果您不确定该项是否存在于
ListA
中,则应使用
FirstOrDefault()
和If语句来检查该项

foreach (var x in ListB)
{
    var itemToChange = ListA.FirstOrDefault(d => d.Name == x.Name);
    if (itemToChange != null)
         itemToChange.Age = x.Age;
}

Where和First返回IEnumerable-您只能修改列表的节点,但不能重新分配

选项0-通用方法 选项1-实施更新方法或手动执行字段更新
要详细说明阿尔肖夫的回答:

ListA.Where(d => d.Name == x.Name).First().CopyFrom(x);
然后在你的个人课上:

public class Person
{
   // ... Name, Id, Age properties...

   public void CopyFrom(Person p)
   {
      this.Name = p.Name;
      this.Id = p.Id;
      this.Age = p.Age;
   }
}

当然,检查空值和所有内容。

您可以根据
Id
ListA
中删除
ListB
的所有元素,将ListB添加到
ListA
,然后使用
Id
进行排序

var newlist = ListA.Where(s => !ListB.Any(p => p.Id == s.Id)).ToList();
newlist.AddRange(ListB);
ListA = newlist.OrderBy(o => o.Id).ToList();

您还可以将Union方法与IEqualityComparer一起使用:

var newList = ListB.Union(ListA, new PersonEqualityComparer());

class PersonEqualityComparer : IEqualityComparer<Person>
{
    public bool Equals(Person person1, Person person2)
    {
        if (person1 == null && person2 == null)
            return true;
        else if ((person1 != null && person2 == null) ||
                (person1 == null && person2 != null))
            return false;

        return person1.Id.Equals(person2.Id);
    }

    public int GetHashCode(Person item)
    {
        return item.Id.GetHashCode();
    }
}
var newList=ListB.Union(ListA,newPersoneQualityComparer());
班级人员资格比较:IEqualityComparer
{
公共布尔等于(个人1,个人2)
{
if(person1==null&&person2==null)
返回true;
else if((person1!=null&&person2==null)||
(person1==null&&person2!=null))
返回false;
返回person1.Id.Equals(person2.Id);
}
public int GetHashCode(个人项目)
{
return item.Id.GetHashCode();
}
}

您必须定义“修改”在本文中的含义case@SamiKuhmonen谢谢,请查看我的编辑。好吧,您正在更改ListA,但您实际返回了ListB(快速查看)是的,我现在检查了它。你的问题是,你正在从列表中返回一个项目,当它通过“First”返回时,你会得到一个对它的引用,即使你改变了值,它也不会反映在列表中。您必须转到列表中的特定位置并替换该值。@Oliver他不是在修改他迭代的列表,而是在使用LINQ从列表中获取特定项,更改它对列表没有任何意义。(只有在更改内部值的情况下)-我会对他拥有的数据执行某种类型的“复制”代码我应该引用什么来使用IndexOf()或Update(),这两种方法都不适用于melet调用您在列表中使用的类“Person”,转到“Person”类并添加“Copy(Person p)”方法。然后对该对象使用浅/深复制。你完成了。没有IndexOf,因为IEnumerable没有索引-它是一个列表方法(确保ListA是真正的列表),更新是您必须编写的东西IndexOf是List类的索引,而Update是一个方法,您应该实现,或者其他用户编写-只需更改年龄字段。如果您有10-20个字段,更新方法将很方便。如果找不到任何项,它将抛出一个
invalidoOperationException
。一个更安全的解决方案是使用
FirstOrDefault
并在进行任何进一步的操作之前检查null。@Merryweather我甚至不打算使用字典来搜索元素:)有没有一种方法可以一次更新所有属性,我的意思是如何更新它,比如
itemToChange=x
,不可能?@super user您必须实现copy或deep copy方法,正如其他人所建议的那样。@super user不建议这样做,因为如果您有一个类作为数据成员-您将对它进行浅层复制,这意味着两个不同的类将引用同一个对象。
public class Person
{
   // ... Name, Id, Age properties...

   public void CopyFrom(Person p)
   {
      this.Name = p.Name;
      this.Id = p.Id;
      this.Age = p.Age;
   }
}
var newlist = ListA.Where(s => !ListB.Any(p => p.Id == s.Id)).ToList();
newlist.AddRange(ListB);
ListA = newlist.OrderBy(o => o.Id).ToList();
var newList = ListB.Union(ListA, new PersonEqualityComparer());

class PersonEqualityComparer : IEqualityComparer<Person>
{
    public bool Equals(Person person1, Person person2)
    {
        if (person1 == null && person2 == null)
            return true;
        else if ((person1 != null && person2 == null) ||
                (person1 == null && person2 != null))
            return false;

        return person1.Id.Equals(person2.Id);
    }

    public int GetHashCode(Person item)
    {
        return item.Id.GetHashCode();
    }
}