Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用LINQ更新列表中的值_C#_.net_Linq_List_C# 4.0 - Fatal编程技术网

C# 如何使用LINQ更新列表中的值

C# 如何使用LINQ更新列表中的值,c#,.net,linq,list,c#-4.0,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;

我有一个列表,我想用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));

但这不会更新myList中的数据。谁能告诉我哪里出了问题

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

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

循环的旧货
怎么样

for(int i = 0; i < myList.Count; i++)
if (myList[i].Name  == "Tom")
{
    myList[i].Marks = 35;
    break;
}
for(int i=0;i
正如其他人指出的,LINQ用于查询数据,而不是进行更新

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

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

无论你认为什么能更好地表达你的意图


但有一件有趣的事:

如果您有如下声明:

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

在不将结果分配回myList的情况下,上述查询将修改原始列表中的值记住,这是一种副作用,不是正确的更新方法。这种修改可以通过将引用参数传递给方法并在那里进行修改来解释但重要的是,应始终避免这种情况。这是一种糟糕的做法,可能会导致代码非常混乱。仅将LINQ用于查询

well@dasblinkenlight代码应该可以工作,但您也可以尝试类似的方法

 var query = from x in list
             where x.Name = yourcondition
             select new { x };
foreach(var item in query)
   item.x.FieldToUpdate = SetValue;

这有点笨重,但很有效,不依赖于传递引用。它将基于旧列表创建一个新列表

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();
尝试:


对象通过引用存储在列表中,因此您可以通过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; }
    }
static void Main(字符串[]args)
{
List testList=新列表()
{
新实体(){Id=1,Text=“Text”},
新实体(){Id=2,Text=“Text2”}
};
WriteLine($“第一个文本值:{testList[1].text}”);
实体entityToEdit=testList.FirstOrDefault(e=>e.Id==2);
if(entityToEdit!=null)
Text=“你好!!”;
Console.WriteLine($“编辑的文本值:{testList[1].text}”);
Console.ReadLine();
}
内部类实体
{
公共int Id{get;set;}
公共字符串文本{get;set;}
}
测试应用程序时,您将得到以下结果:

第一个文本值:Text2

编辑文本值:您好


只需将值分配回集合即可实现上述功能

myList = myList
        .Where(w => w.Name == "Tom")
        .Select(w=> { w.Marks = 35; return w})
        .ToList();
Select()
与任何其他LINQ方法一样,不会更改源集合,而是返回新集合

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

myList = myList.Where(w => w.Name == "Tom").Select(w => { w.Marks = 35; return w}).ToList();
或者在单独的foreach循环中指定
标记
属性

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

LINQ
用于查询未更新的数据。最好使用
foreach
循环来完成。我尝试了foreach(myList中的item.where(w=>w.Name==“Tom”){item.Marks=35;}但出现了一个错误-无法修改'item'的成员,因为它是'foreach迭代变量'。发布的代码没有编译-缺少参数,数据类型不匹配,大小写不一致,在构造函数中隐藏字段,等等。如果您发布了一些更接近原始代码并实际编译的内容,那么问题可能会很明显。在查询之后,简单的
foreach
应该可以工作。您声明生成“无法修改”项“”的成员的代码不起作用。如果
Student
struct
而不是
,则会生成此代码。您提供的示例代码无法编译。您能提供您正在使用的实际代码吗?这会产生错误-无法修改“item”的成员,因为它是“foreach迭代变量”,无法修改IEnumerable。这不会产生错误。这是一个非常好的代码,同时也进行了修改,但并不确定是否有否决票。@EhsanSajjad这段代码中没有任何内容会试图修改
IEnumerable
修改
IEnumerable
的成员,另一方面,这是一个100%公平的游戏。@user3625024您不应该得到任何错误,前提是您的
学生
课程与您的问题中所示的课程相同。我添加了演示来展示它是如何工作的。+1这指出了一个让我发疯的重要点,因为许多帖子都提供了你的反模式作为答案,我想知道我是否正确理解LINQ中的Q。谢谢:-)更多信息请参见本帖:其他答案已经说明了这一点。我不认为你的回答会增加很多。这并不能解释任何事情,OP只是问他们做错了什么。如果只包含代码的答案还包含解释,那么它们将更有价值。欢迎使用堆栈溢出!虽然这段代码片段可能是解决方案,但包含解释确实有助于提高文章的质量。记住,你是在为将来的读者回答这个问题,而那些人可能不知道你的代码建议的原因。@Kurtvandenbren虽然这是一篇老文章,但你的意思是说,将来的读者将无法阅读这个问题来理解为什么会有这个代码建议?因为我读了所有的答案,并且理解了所有的答案,尽管很少有答案是没有解释的。
myList = myList
        .Where(w => w.Name == "Tom")
        .Select(w=> { w.Marks = 35; return w})
        .ToList();
myList = myList.Where(w => w.Name == "Tom").Select(w => { w.Marks = 35; return w}).ToList();
myList.Where(w => w.Name == "Tom").ToList().ForEach(w => w.Marks = 35);