使用LINQ更新IEnumerable对象的简单方法

时间:2010-10-14 06:05:46

标签: c# linq

假设我有一个这样的业务对象,

class Employee
    {
        public string name;
        public int id;
        public string desgination;
        public int grade;
    }

    List<Employee> lstEmp = new List<Employee>()
        {
            new Employee() { name="A",desgination="SE",id=1},
            new Employee() { name="b",desgination="TL",id=2},
            new Employee() { name="c",desgination="PL",id=3},
            new Employee() { name="d",desgination="SE",id=4},
            new Employee() { name="e",desgination="SSE",id=5},
        };

如果我想将员工等级更新为3,其名称为“SE”,那么我必须写这样的东西

lstEmp=lstEmp.Select(x =>
            {
                x.grade = (x.desgination == "SE") ? 3 : x.grade;
                    return x;
            }).ToList();

但是在使用select时它会每次生成新的employee对象,而不是更新现有的lstEmp,所以我必须将更新的列表重新分配给lstEmp。

在我看来,它会影响频繁更新大型更新时的性能。有解决方法吗?

4 个答案:

答案 0 :(得分:18)

实际上,您现有的Select调用 修改原始对象本身 - 它不会创建新的员工对象。是什么让你认为创建新的Employee实例?毕竟,你没有在lambda表达式中的任何地方new Employee

您可以在不调用Select的情况下迭代调用ToList的结果,之后您仍会看到更改。这意味着您的投影具有副作用 - 这通常是一个坏主意。你必须让某些东西迭代投影的结果。例如,只需拨打Count()即可。在许多情况下,LINQ查询使用延迟执行:在需要结果之前,它们不应用投影/谓词/等。

LINQ旨在以功能性方式工作:不鼓励使用副作用,就像您不希望数据库上的普通SELECT查询更改其查询的表的内容一样。无副作用代码在可读性和推理代码的能力方面非常出色。

如果您想更改值而不是创建新值,我建议使用简单的foreach循环。这不是LINQ的设计目标。但是,我会亲自尝试坚持不可变类型,使用LINQ,并在你去的时候测量性能 - 我怀疑你会发现在很多情况下它并没有你想象的那么糟糕。

答案 1 :(得分:10)

我认为默认的LINQ方法不支持内联更新。但是你可以创建自己的扩展方法来实现这个

  public static void Update<TSource>(this IEnumerable<TSource> outer, Action<TSource> updator)
        {
            foreach (var item in outer)
            {
                updator(item);
            }


        }

并像这样使用

 lstEmp.Update(x => x.grade = (x.desgination == "SE") ? 3 : x.grade);

答案 2 :(得分:1)

我会说LINQ主要用于在获取数据后选择数据,可以使用ForEach构造来更新数据

答案 3 :(得分:-2)

lstEmp = lstEmp.Select(X => new Employee
        {
            desgination =X.desgination ,
            grade =X.desgination=="SE"?3:X.grade ,
            id=X.id ,
            name =X.name 
        }).ToList();