【问题标题】:How to update an object in a List<> in C#如何在 C# 中更新 List<> 中的对象
【发布时间】:2011-11-03 15:18:09
【问题描述】:

我有一个List&lt;&gt; 的自定义对象。

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

最快的方法是什么?

【问题讨论】:

    标签: c# asp.net list generics


    【解决方案1】:

    使用 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;
    

    【讨论】:

    • 感谢 CKoenig,这会得到对 obj 或 value(copy) 的引用吗?换句话说,列表中的对象会改变吗?
    • 我认为如果对象是结构类型,这将不起作用,将其设为类:)
    • 因为你有一个自定义对象列表(假设它是一个类而不是一个结构),你正在处理一个引用类型,它将是对该对象的引用并且修改它会“持久化” " - 它将修改集合中的对象。
    • 这将找到引用(所以是的,它将是列表中的对象)并且它也应该与结构一起使用 - 但老实说,我必须尝试确定存在 - 但我没有不明白为什么不提款机
    • @CKoenig - 它不适用于结构,在下面添加了一个带有代码示例的响应来演示
    【解决方案2】:

    只是为了补充 CKoenig 的回应。只要您处理的类是引用类型(如类),他的答案就会起作用。如果自定义对象是一个结构,这是一个值类型,.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

    将struct改成class,输出为10,12,145

    HTH

    【讨论】:

    • 好的 - 谢谢。我的猜测是你得到了对结构的引用,而不是本地副本。
    【解决方案3】:

    或者没有 linq

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

    【讨论】:

    • 是的,这是显而易见的答案,但我不想使用 foreach,我想这是最慢的方法
    • 谁能评论一下上面的LINQ方法是否真的比这个更有效?
    • 如果有差异,可能是linq版本比较慢。
    • @Burjua 感觉是我们可以看到在 foreach 块中发生的实际循环,而在 Linq/Lambda 中我们看不到,因此我们假设 foreach 较慢并尽量避免它。现实是 foreach/for/while 循环要快得多。
    • 好吧,更慢/更快,我不知道是哪个……但就我而言,无论如何我都在处理小记录,不想多想。这行得通!很好的休息;
    【解决方案4】:

    也可以试试。

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

    【讨论】:

    • 这适用于列表或数组,但不适用于 IEnumerable
    【解决方案5】:
    var itemIndex = listObject.FindIndex(x => x == SomeSpecialCondition());
    var item = listObject.ElementAt(itemIndex);
    item.SomePropYouWantToChange = "yourNewValue";
    

    【讨论】:

    • 无需从列表中删除对象并重新插入(非常低效)。对象是引用类型。一旦你有一个对象的引用,只需更新对象,因为它是一个并且与列表中的对象相同。
    • 还有一个建议。 FindIndex 可能返回 -1,在这种情况下 ElementAt 会抛出异常。
    【解决方案6】:

    你可以这样做:

    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;
    }
    

    【讨论】:

      【解决方案7】:

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

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

      myList.Single(x => x.MyProperty == myValue).OtherProperty = newValue;
      

      【讨论】:

      • 正好解决了我的问题,因为我不想创建一个新的 List,而只想更新我的 List 中一个对象的 ONE 属性
      【解决方案8】:

      我在一行代码中找到了一种方法:

      yourList.Where(yourObject => yourObject.property == "yourSearchProperty").Select(yourObject => { yourObject.secondProperty = "yourNewProperty"; return yourObject; }).ToList();
      

      【讨论】:

        【解决方案9】:
        //Find whether the element present in the existing list
        
            if (myList.Any(x => x.key == "apple"))
               {
                  //Get that Item
                 var item = myList.FirstOrDefault(x => x.key == ol."apple");
                //update that item
                 item.Qty = "your new value";
               }
        

        【讨论】:

          猜你喜欢
          • 2023-04-02
          • 1970-01-01
          • 1970-01-01
          • 2014-05-23
          • 2012-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多