如何使用LINQ更新List中的值

时间:2015-05-05 14:21:46

标签: c# .net linq list c#-4.0

我有一个列表,我想用LINQ更新。

class Student
{
    private string name;
    private int marks;
    public string Name { get; set;}
    public int Marks { get; set; }
    public Student(string name, int marks)
    {
        Name = name;
        Marks = marks;
    }
}

List<Student> myList = new List<Student>();
myList.Add(new Student("John", 10));
myList.Add(new Student("Tom", 20));

现在我想使用LINQ更新列表,以便只更新John的标记。我使用以下语法:

myList.Where(w => w.Name == "Tom").Select(w=> { w.Marks = 35; return w});

但这不会更新myList中的数据。有人能告诉我哪里出错了。

9 个答案:

答案 0 :(得分:22)

LINQ用于查询,而不是用于更新数据。使用LINQ获取要修改的项目,然后在foreach循环中修改它们:

foreach ( var tom in myList.Where(w => w.Name == "Tom")) {
    tom.Marks = 35;
}

Demo.

答案 1 :(得分:5)

正如其他人所指出的那样,LINQ用于查询数据,而不是用于更新。

您应该迭代列表,并修改您的值,如:

foreach (var student in myList)
{
    if (student.Name == "Tom")
    {
        student.Marks = 35;
    }
}

或者

foreach (var student in myList.Where(r => r.Name == "Tom"))
{
    student.Marks = 35;
}

无论你认为什么更好地传达了意图用途。

但这是一件有趣的事情:

如果您有以下声明:

myList.Where(w => w.Name == "Tom").Select(w => w.Marks = 35).ToList();

如果不将结果分配回myList,则上述查询将修改原始列表中的值。 请记住,这是一种副作用,而不是正确的更新方式。这是修改可以通过传递给方法并在那里进行修改的引用参数来解释。 但重要的是,应始终避免这种情况。这是一种不好的做法,可能导致真正令人困惑的代码。使用LINQ仅查询。

答案 2 :(得分:3)

尝试:

myList .Where(w=> w.Name  == "dTomi").ToList().ForEach(i => i.Marks  = 35);

答案 3 :(得分:1)

Select()与其他LINQ方法一样,不会更改源集合,而是返回一个新集合。

因此,您应该将该新集合分配给myList

myList = myList.Where(w => w.Name == "Tom").Select(w => { w.Marks = 35; return w}).ToList();

或在单独的foreach循环中分配Marks属性

myList.Where(w => w.Name == "Tom").ToList().ForEach(w => w.Marks = 35);

答案 4 :(得分:0)

旧的for循环

怎么样?
for(int i = 0; i < myList.Count; i++)
if (myList[i].Name  == "Tom")
{
    myList[i].Marks = 35;
    break;
}

答案 5 :(得分:0)

以及@dasblinkenlight代码应该可以工作,但你也可以尝试这样的东西

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/action_zoom"
        android:title="@string/action_zoom"
        android:showAsAction="always"
        android:actionViewClass="android.widget.ZoomControls" />
</menu>

答案 6 :(得分:0)

这有点笨重但有效,并且不依赖于传递参考。它会根据旧的列表创建一个新列表。

var myList=myList.Select(l=>new Student { 
   l.Name,
   Marks=l.Name=="Tom"?35:l.Marks}).ToList();

或者更愚蠢:

var myList=myList.Where(l=>l.Name!="Tom").Union(
  myList.Where(l=>l.Name=="Tom").Select(l=>new Student { 
   l.Name,
   Marks=35})).ToList();

答案 7 :(得分:0)

对象通过引用存储在列表中,因此您可以通过linq恢复对象然后进行编辑,它将反映列表中的更改。

实施例

    static void Main(string[] args)
        {
            List<Entity> testList = new List<Entity>()
            {
                new Entity() {Id = 1, Text = "Text"},
                new Entity() {Id = 2, Text = "Text2"}
            };

            Console.WriteLine($"First text value:{testList[1].Text}");

            Entity entityToEdit = testList.FirstOrDefault(e => e.Id == 2);
            if (entityToEdit != null)
                entityToEdit.Text = "Hello You!!";

            Console.WriteLine($"Edited text value:{testList[1].Text}");

            Console.ReadLine();
        }

 internal class Entity
    {
        public int Id { get; set; }
        public String Text { get; set; }
    }

测试应用程序,您将获得以下结果:

  

第一个文字值:Text2

     

编辑文字值:你好!!

答案 8 :(得分:0)

只需将值分配回集合即可实现

myList = myList
        .Where(w => w.Name == "Tom")
        .Select(w=> { w.Marks = 35; return w})
        .ToList();