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.