如何在C#中更新List <>中的对象


81

我有一个List<>自定义对象。

我需要通过一些唯一的属性在此列表中找到一个对象,并更新该对象的另一个属性。

最快的方法是什么?

Answers:


108

使用Linq查找可以执行的对象:

var obj = myList.FirstOrDefault(x => x.MyProperty == myValue);
if (obj != null) obj.OtherProperty = newValue;

但是在这种情况下,您可能想要将列表保存到字典中,而改用它:

// ... define after getting the List/Enumerable/whatever
var dict = myList.ToDictionary(x => x.MyProperty);
// ... somewhere in code
MyObject found;
if (dict.TryGetValue(myValue, out found)) found.OtherProperty = newValue;

4
感谢CKoenig,这将获得对obj或值(副本)的引用吗?换句话说,列表内的对象会改变吗?
2011年

4
我认为如果对象的类型为struct,则将其
设为

27
因为您有一个自定义对象列表(假设它是一个类而不是一个结构),所以您要处理一个引用类型,它将成为对该对象的引用,对其进行修改将“持久”-它将在集合。
马特·罗伯茨

1
这将找到引用(所以是的,它将是列表中的对象),它也应该与结构一起工作-但老实说,我不得不尝试确保在那里-但我不明白为什么不使用ATM
Carsten

2
@CKoenig-它不适用于结构,在下面添加了带有示例代码的响应,以进行演示
Matt Roberts

29

只是为了增加CKoenig的回应。只要您要处理的类是引用类型(如类),他的答案就会起作用。如果自定义对象是一个struct,则它是一个值类型,并且的结果.FirstOrDefault将为您提供该值的本地副本,这将意味着它不会持久返回到集合,如以下示例所示:

struct MyStruct
{
    public int TheValue { get; set; }
}

测试代码:

List<MyStruct> coll = new List<MyStruct> {
                                            new MyStruct {TheValue = 10},
                                            new MyStruct {TheValue = 1},
                                            new MyStruct {TheValue = 145},
                                            };
var found = coll.FirstOrDefault(c => c.TheValue == 1);
found.TheValue = 12;

foreach (var myStruct in coll)
{
    Console.WriteLine(myStruct.TheValue);
}
Console.ReadLine();

输出为10,1,145

将结构更改为类,输出为10,12,145

高温超导


好,谢谢。我的猜测是,您也将引用该结构,而不是本地副本。
卡斯滕

18

有无linq

foreach(MyObject obj in myList)
{
   if(obj.prop == someValue)
   {
     obj.otherProp = newValue;
     break;
   }
}

1
是的,这是显而易见的答案,但是我不想使用foreach,我想这是最慢的方法
Burjua 2011年

谁能评论上面的LINQ方法实际上是否比这种方法更有效?

6
如果存在任何差异,则linq版本可能较慢。
Erix 2011年

7
@Burjua的看法是,我们可以看到在foreach块中发生了实际的循环,而在Linq / Lambda中则没有,因此我们假定foreach较慢并尝试避免它。现实是foreach / for / while循环要快得多。
harsimranb 2014年

慢点/快点,我不知道哪个...但是就我而言,我无论如何都在处理小记录,并且不想考虑太多。这工作了!休息时感觉很好;
Anthony Griggs

9

也可以尝试。

 _lstProductDetail.Where(S => S.ProductID == "")
        .Select(S => { S.ProductPcs = "Update Value" ; return S; }).ToList();

3
这适用于列表或数组,但不适用于IEnumerable
Lord Darth Vader

6
var itemIndex = listObject.FindIndex(x => x == SomeSpecialCondition());
var item = listObject.ElementAt(itemIndex);
item.SomePropYouWantToChange = "yourNewValue";

1
无需从列表中删除该对象并重新插入它(效率很低)。对象是引用类型。一旦有了对对象的引用,只需更新该对象即可,因为它与列表中的对象相同且相同。
humbads '19

还有一个建议。FindIndex可能返回-1,在这种情况下ElementAt将引发异常。
humbads '19

4

你可以做这样的事情:

if (product != null) {
    var products = Repository.Products;
    var indexOf = products.IndexOf(products.Find(p => p.Id == product.Id));
    Repository.Products[indexOf] = product;
    // or 
    Repository.Products[indexOf].prop = product.prop;
}

0

今天,这是一个新发现-在学习了类/结构参考课之后!

如果您知道将找到该项目,则可以使用Linq和“ Single” ,因为Single返回一个变量...

myList.Single(x => x.MyProperty == myValue).OtherProperty = newValue;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.