C# LINQ:选择一个对象并更改某些属性而不创建新对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/807797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LINQ: Select an object and change some properties without creating a new object
提问by Rob Volk
I want to change some properties of a LINQ query result object without creating a new object and manually setting every property. Is this possible?
我想更改 LINQ 查询结果对象的某些属性,而无需创建新对象并手动设置每个属性。这可能吗?
Example:
例子:
var list = from something in someList
select x // but change one property
采纳答案by JaredPar
I'm not sure what the query syntax is. But here is the expanded LINQ expression example.
我不确定查询语法是什么。但这里是扩展的 LINQ 表达式示例。
var query = someList.Select(x => { x.SomeProp = "foo"; return x; })
What this does is use an anonymous method vs and expression. This allows you to use several statements in one lambda. So you can combine the two operations of setting the property and returning the object into this somewhat succinct method.
这样做是使用匿名方法 vs 和表达式。这允许您在一个 lambda 中使用多个语句。所以你可以将设置属性和返回对象这两个操作结合到这个有点简洁的方法中。
回答by Daniel Brückner
It is not possible with the standard query operators - it is Language Integrated Query, not Language Integrated Update. But you could hide your update in extension methods.
使用标准查询运算符是不可能的 - 它是语言集成查询,而不是语言集成更新。但是您可以在扩展方法中隐藏您的更新。
public static class UpdateExtension
{
public static IEnumerable<Car> ChangeColorTo(
this IEnumerable<Car> cars, Color color)
{
foreach (Car car in cars)
{
car.Color = color;
yield return car;
}
}
}
Now you can use it as follows.
现在您可以按如下方式使用它。
cars.Where(car => car.Color == Color.Blue).ChangeColorTo(Color.Red);
回答by Joshua Belden
There shouldn't be any LINQ magic keeping you from doing this. Don't use projection though that'll return an anonymous type.
不应该有任何 LINQ 魔法阻止你这样做。尽管会返回匿名类型,但不要使用投影。
User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"
That will modify the real object, as well as:
这将修改真实对象,以及:
foreach (User u in UserCollection.Where(u => u.Id > 10)
{
u.Property = SomeValue;
}
回答by Solmead
var item = (from something in someList
select x).firstordefault();
Would get the item
, and then you could do item.prop1=5;
to change the specific property.
会得到item
,然后你可以item.prop1=5;
改变特定的属性。
Or are you wanting to get a list of items from the db and have it change the property prop1
on each item in that returned list to a specified value?
If so you could do this (I'm doing it in VB because I know it better):
或者您是否想从数据库中获取项目列表,并将prop1
该返回列表中每个项目的属性更改为指定值?如果是这样,你可以这样做(我在 VB 中这样做,因为我更了解它):
dim list = from something in someList select x
for each item in list
item.prop1=5
next
(list
will contain all the items returned with your changes)
(list
将包含随您的更改返回的所有项目)
回答by Jon Spokes
If you just want to update the property on all elements then
如果您只想更新所有元素的属性,那么
someList.All(x => { x.SomeProp = "foo"; return true; })
回答by kazem
User u = UserCollection.Single(u => u.Id == 1);
u.FirstName = "Bob"
回答by Jan Zahradník
I prefer this one. It can be combined with other linq commands.
我更喜欢这个。它可以与其他 linq 命令结合使用。
from item in list
let xyz = item.PropertyToChange = calcValue()
select item
回答by Stefan R.
Since I didn′t find the answer here which I consider the best solution, here my way:
由于我没有在这里找到我认为最好的解决方案的答案,这里是我的方式:
Using "Select" to modify data is possible, but just with a trick. Anyway, "Select" is not made for that. It just executes the modification when used with "ToList", because Linq doesn′t execute before the data is being needed. Anyway, the best solution is using "foreach". In the following code, you can see:
使用“选择”来修改数据是可能的,但只是一个技巧。无论如何,“选择”不是为此而生的。它只是在与“ToList”一起使用时执行修改,因为 Linq 在需要数据之前不会执行。无论如何,最好的解决方案是使用“foreach”。在以下代码中,您可以看到:
class Person
{
public int Age;
}
class Program
{
private static void Main(string[] args)
{
var persons = new List<Person>(new[] {new Person {Age = 20}, new Person {Age = 22}});
PrintPersons(persons);
//this doesn't work:
persons.Select(p =>
{
p.Age++;
return p;
});
PrintPersons(persons);
//with "ToList" it works
persons.Select(p =>
{
p.Age++;
return p;
}).ToList();
PrintPersons(persons);
//This is the best solution
persons.ForEach(p =>
{
p.Age++;
});
PrintPersons(persons);
Console.ReadLine();
}
private static void PrintPersons(List<Person> persons)
{
Console.WriteLine("================");
foreach (var person in persons)
{
Console.WriteLine("Age: {0}", person.Age);
;
}
}
}
Before "foreach", you can also make a linq selection...
在“foreach”之前,您还可以进行 linq 选择...
回答by Pierre
If you want to update items with a Where
clause, using a .Where(...) will truncate your results if you do:
如果你想用一个Where
子句更新项目,如果你这样做,使用 .Where(...) 将截断你的结果:
mylist = mylist.Where(n => n.Id == ID).Select(n => { n.Property = ""; return n; }).ToList();
You can do updates to specific item(s) in the list like so:
您可以对列表中的特定项目进行更新,如下所示:
mylist = mylist.Select(n => { if (n.Id == ID) { n.Property = ""; } return n; }).ToList();
Always return item even if you don't make any changes. This way it will be kept in the list.
即使您不进行任何更改,也始终退回商品。这样它就会被保留在列表中。
回答by Informitics
We often run into this where we want to include a the index value and first and last indicators in a list without creating a new object. This allows you to know the position of the item in your list, enumeration, etc. without having to modify the existing class and then knowing whether you're at the first item in the list or the last.
我们经常遇到这种情况,我们希望在列表中包含索引值以及第一个和最后一个指标,而无需创建新对象。这使您可以知道项目在列表、枚举等中的位置,而无需修改现有类,然后知道您是在列表中的第一项还是最后一项。
foreach (Item item in this.Items
.Select((x, i) => {
x.ListIndex = i;
x.IsFirst = i == 0;
x.IsLast = i == this.Items.Count-1;
return x;
}))
You can simply extend any class by using:
您可以简单地使用以下方法扩展任何类:
public abstract class IteratorExtender {
public int ListIndex { get; set; }
public bool IsFirst { get; set; }
public bool IsLast { get; set; }
}
public class Item : IteratorExtender {}