C#でList <>のオブジェクトを更新する方法


82

私が持っているList<>カスタムオブジェクトのを。

このリストで一意のプロパティを見つけて、このオブジェクトの別のプロパティを更新する必要があります。

それを行う最も簡単な方法は何ですか?

回答:


109

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
オブジェクトが構造体型の場合、これは機能しないと思います

27
カスタムオブジェクトのリストがあるため(構造体ではなくクラスであると想定)、参照型を処理します。これはそのオブジェクトへの参照になり、変更すると「永続化」されます。コレクション。
マットロバーツ

1
これは参照を見つけ(そうです、それはリスト内のオブジェクトになります)、構造体でも機能するはずです-しかし正直に言うと、そこにあることを確認する必要がありました-しかし、なぜATMではないのかわかりません
Carsten

2
@ CKoenig-構造体では機能しません。以下に、デモ用のコード例を含む応答を追加しました
Matt Roberts

30

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です

構造体をクラスに変更すると、出力は10,12,145になります。

HTH


わかりました-ありがとう。私の推測では、ローカルコピーではなく、構造体への参照も取得していると思います。
カルステン

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

かなり遅い/速い私はどちらかわかりません...しかし私の場合、私はとにかく小さなレコードを扱っていて、それについてあまり考えたくありませんでした。これはうまくいきました!休憩とのいい感じ。
アンソニー・グリッグス

9

試すこともできます。

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

3
これはリストまたは配列で機能しますが、IEnumerableでは機能しません
ロードダースベイダー

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

2
リストからオブジェクトを削除して再挿入する必要はありません(非常に非効率的です)。オブジェクトは参照型です。オブジェクトへの参照を取得したら、リスト内のオブジェクトと同じオブジェクトを更新するだけです。
humbads

1
もう1つの提案。FindIndexは-1を返す場合があります。その場合、ElementAtは例外をスローします。
humbads

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

これは今日の新しい発見でした-クラス/構造体のリファレンスレッスンを学んだ後です!

Singleは変数を返すため、アイテムが見つかることがわかっている場合は、Linqと "Single"を使用できます...

myList.Single(x => x.MyProperty == myValue).OtherProperty = newValue;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.