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또는 가치 (복사) 를 얻을 수 있습니까? 즉, 목록 내의 개체가 변경됩니까?
Burjua

4
나는 객체 형 구조체의 경우이 작업 :) 그것을 수업을하지 않을 것이라고 생각
사라 S.에게

27
사용자 정의 객체 목록이 있기 때문에 (구조체가 아니라 클래스라고 가정) 참조 유형을 다루고 있습니다. 해당 객체에 대한 참조가되고 수정하면 "지속"됩니다. 컬렉션.
Matt Roberts

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


알았어 고마워. 내 생각 엔 로컬 복사본 대신 구조체에 대한 참조를 얻는 것입니다.
Carsten

18

또는 linq없이

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

1
예,이 그것을 할 수있는 가장 느린 방법입니다 생각, 이것은 명백한 대답은,하지만 난 foreach 문을 사용하지 않으
Burjua

누구든지 위의 LINQ 방법이 실제로이 방법보다 더 효율적인지에 대해 언급 할 수 있습니까?
의사

6
차이가 있으면 linq 버전이 더 느릴 수 있습니다.
Erix

7
@Burjua 우리는 foreach 블록에서 발생하는 실제 루프를 볼 수있는 반면 Linq / Lambda에서는 그렇지 않으므로 foreach가 더 느리다고 가정하고이를 피하려고합니다. 현실은 foreach / for / while 루프가 훨씬 빠릅니다.
harsimranb

더 느리게 / 빠르게 나는 어느 것이인지 모르겠습니다.하지만 제 경우에는 어쨌든 작은 레코드를 다루고 있었고 그것에 대해 많이 생각하고 싶지 않았습니다. 이것은 효과가 있었다! 휴식과 함께 좋은 터치;
Anthony Griggs

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
하나 더 제안합니다. 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.