C#:更新列表中的项目值我正在寻找一种方法来更新列表中的元素,而无需自己枚举它。我得到了ClassMyProjects,其中包含一个名为Projects的列表。我想找到MyProjects.Projects-Class,其中Class1(Name)的成员属性等于值“开销”。什么有效:foreach(ProjectprjinMyProjects.Projects){if(prj.Name=="Overhead")prj.IsActive=true;};但是,我尝试使用Linq来做同样的事情,但是将它写在一行中却失败了。这可能吗?我不喜欢以上述方式迭代的原因是我已经在这段代码中迭代了整个列表,并认为可能有一种更奇特的方式:)你不应该试图将所有内容都归结为一行-保持尽可能短。在这种情况下,您可以使用:foreach(varprojectinMyProjects.Projects.Where(p=>p.Name=="Overhead")){project.IsActive=true;}那就是使用LINQ的查询部分,这就是LINQ的Q所代表的意思。我强烈建议您不要像Mayank的回答那样更改LINQ调用中的项目。它很容易出错(原始答案不起作用)并且违背了LINQ的精神。这是可读的,IMO。它与原始代码完全相同,请注意-如果每个项目可能是您要更新的项目,则无法避免迭代列表中每个项目的内容。编辑:只是为了笑,如果你真的,真的想用非常简单的代码来做,你可以使用://DON'TUSETHIS!MyProjects.Project.Count(p=>p.Name=="开销"&&(p.IsActive=true));在这里,我们使用&&短路的事实来避免评估赋值(p.IsActive=true),除非条件匹配。使用bool值对属性进行bool操作很方便,因为这意味着我们无需执行任何其他操作即可使其成为&&运算符的有效第二个操作数。我们使用Count()来完全评估结果而不创建任何其他列表等-我们使用带有谓词的版本来避免甚至需要Where调用,这是以前版本所做的。(LastOrDefault也可以。)但这都是一种可怕的滥用,永远不应该出现在任何实际代码中。我想出了一种方法,可以在不滥用LINQ的情况下将其简化为一行,因为我只是将它用于查询部分(过滤器)并使用自定义扩展方法来执行属性设置操作。您仍然必须枚举项目(您必须这样做),但您可以将其隐藏在扩展方法中。我怀疑您是否真的不在乎是否枚举该项目,您只是不喜欢foreach循环在主代码中占用的可见空间量。使用此扩展方法:publicstaticIEnumerableSetProperty(thisIEnumerablelist,Actionaction){foreach(variteminlist){action.Invoke(item);}返回列表;这使您可以将其简化为一行可读。Projects.Where(p=>p.Name=="Overhead").SetProperty(p=>p.IsActive=true);完整的测试程序:usingSystem;使用System.Collections.Generic;使用System.Linq;namespaceConsoleApplication2{classProgram{staticvoidMain(string[]args){varProjects=newList(){newProject(){Name="Overhead",IsActive=false},newProject(){Name="Nadfadfs",IsActive=false},newProject(){Name="Overhead",IsActive=false},newProject(){Name="dasfasdf",IsActive=false}};打印项目列表(项目);Console.WriteLine("--设置属性--");Projects.Where(p=>p.Name=="Overhead").SetProperty(p=>p.IsActive=true);打印项目列表(项目);Console.WriteLine("按任意键退出。");控制台.ReadKey();}staticvoidPrintProjectList(IEnumerableprojects){foreach(varpinprojects){Console.WriteLine($"Name:{p.Name}IsActive:{p.IsActive}");}}}classProject{publicstringName{get;放;}publicboolIsActive{得到;放;}}民众staticclassExtensions{publicstaticIEnumerableSetProperty(thisIEnumerablelist,Actionaction){foreach(variteminlist){action.Invoke(item);}返回列表;}}}输出:名称:OverheadIsActive:False名称:NadfadfsIsActive:False名称:OverheadIsActive:False名称:dasfasdfIsActive:False-设置属性-名称:OverheadIsActive:True名称:OverheadIsActive:False名称:OverheadIsActive:TrueName:OverheadIsActive:False事实证明,我的SetProperty函数与框架中已经内置的ForEach非常相似,主要区别在于我的函数可以在任何IEnumerable上。由于EricLippert在他的博客中指出的原因(感谢JonSkeet指出这一点),这种语法受到一些人的喜爱,而另一些人则对此感到厌恶。另请参阅Microsoft团队的讨论。我会留给你自己得出结论。此外,将其称为SetProperty有点不准确,因为您可以对集合中的项目执行任何操作。您可以将其称为ForEach,但这与框架冲突。我称它不是积极的,但也许是PerformAction。以下Linq语句应该有效MyProjects.Projects.Where(p=>p.Name=="Overhead").Select(x=>{x.IsActive=true;returnx;}).ToList();根据@JonSkeet、@TimSchmelter和@LeandroSoares的评论,上面的代码真的很糟糕。这里有一些原因。以上就是C#学习教程:C#:UpdateitemvalueinList分享的所有内容,如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——call.ToList()将导致整个惰性集合被执行并加载到内存中。上面的代码可读性不是很好,也很难维护。上面的代码滥用了API,因为它强制API做一些它不是为它设计的。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
