2012-10-20 17 views
33

Bazı listeye sahibim (burada T özel bir sınıftır ve sınıfın bazı özellikleri vardır). Ben istiyorum Lambda İfadeleri kullanarak bunun inide bir veya daha fazla değerleri değiştirmek için bilmek, bu nedenle sonuç feryat foreach döngüsünde aynı olacaktır:Listenin içinde bir miktar değeri değiştirin <T>

NOT: Liste içine birden çok öğe içerir (çoklu satır)

 foreach (MyClass mc in list) 
     { 
      if (mc.Name == "height") 
       mc.Value = 30; 
     } 

Ve bu linq sorgusu (Lambda ifadeleri kullanarak), ancak üst foreach döngüsü olarak aynı değildir, sadece listeden 1 öğe (bir satır) döndürür!

İstediğim tüm öğeleri (tüm satırlar) döner ve SADECE uygun olanı (WHERE uzatma yöntemi (ler) de belirtilen ürün chnages yani,

list = list.Where(w => w.Name == "height").Select(s => { s.Value = 30; return s; }).ToList(); 

NOT:. Bu 2 örnek aynı değil! Ben, linq sadece 1 madde (bir satır) döndürür ve bu ben istemiyorum bir şey, ben de listeden tüm öğeleri gerekir (foreach döngü gibi, sadece değişiklikler yapar, ama değil Herhangi bir öğeyi kaldırın ...

+5

* Neden * lambda ifadelerini kullanmak istiyorsunuz? 'Foreach' kodu iyi çalışıyor ve basit. LINQ, * verileri sorgulamak için değil, sorgulamak içindir. –

+1

Tanım olarak, yalnızca eşleşen kayıtları döndürür. Temel olarak: istediğin bu değil - sadece foreach kullanın –

+0

Merhaba Jon, foreach döngü biliyorum çünkü hamuru ve daha hızlı, ama öğrenmek istiyorum, hepsi bu. Bazı "küçük" kodlar için sadece iyi yapacağız. Ama asıl mesele çoğunlukla yaşıyor. –

cevap

64

ForEach'u kullanabilirsiniz, ancak IEnumerable<T> kodunu bir List<T> numaralı telefona dönüştürmeniz gerekir.

list.Where(w => w.Name == "height").ToList().ForEach(s => s.Value = 30); 
+0

Bu, yeni bir liste oluşturur. Name! = "Height" öğesinin Chopps olduğu yer. – Tilak

+0

Yeni bir liste oluşturur - VE yalnızca WHERE maddesine göre öğeler döndürür. İstediğim bir örnek değil. –

+0

@MitjaBonca kötü, sorunuzu yanlış anladım. Yukarıdaki düzenlemeye bakın. – McGarnagle

2

Bir deyim lambda olan bir uzantıyı kullanabilirsiniz, ancak orijinal foreach döngü daha okunabilir ve yerinde listesini düzenlemenin yerine yeni bir liste yaratıyor.

var result = list.Select(i => 
    { 
     if (i.Name == "height") i.Value = 30; 
     return i; 
    }).ToList(); 

Uzatma Yöntemi Böyle bir şey yapabiliriz

public static void SetHeights(this IEnumerable<MyClass> source, int value) 
{ 
    foreach (var item in source) 
    { 
     if (item.Name == "height") 
     { 
      item.Value = value; 
     } 

     yield return item; 
    } 
} 

var result = list.SetHeights(30).ToList(); 
+0

Bloktan kaçınmak mümkün mü? Seçme uzantısı yöntemini tanımlamak ister misiniz? –

+0

Evet, özel bir uzantı yöntemi tanımlayabilirsiniz, ancak orijinal foreach daha az belirsiz ve bakımı daha kolaydır ve maliyetli olabilecek yeni bir liste oluşturmaz. – devdigital

+0

Bir sünnet çıkarma yöntemi nasıl yapılacağını biliyorum, sadece kodu ile ilgili "kısa" bir şekilde yapmak mümkün olup olmadığını merak ediyorum ?! @Robin'in gösterdiği gibi, sadece onun kodu çalışmıyor! –

-2

:

var newList = list.Where(w => w.Name == "height") 
       .Select(s => new {s.Name, s.Value= 30 }).ToList(); 

Ama LINQ istediğiniz ise sorgulamak için çünkü doğrusu foreach kullanmayı tercih ediyorum verileri düzenleyin.

+0

Daha önce bununla bir deneme yaptım, ama bir istisna aldım: "Geçersiz anonim tip üye declarator. Anonim üye üyeleri, üye atama, basit ad veya üye erişimi ile bildirilmelidir.". Bu "s.Value = 30" içindir. –

+0

Örnek değil İstiyorum, hatta çalışmıyor. –

8

Herhalde Tüm öğeleri korumak istiyorsanız orijinal listesine bir başvuru tutun (ben onun değil saf linq biliyorum) bu ile gitmek istiyorum ve güncellenen değer varsa içindedir bulmalısınız:

foreach (var mc in list.Where(x => x.Name == "height")) 
    mc.Value = 30; 
1

Nasıl hakkında list.Find(x => x.Name == "height").Value = 20; Bu iyi çalışıyor. Onun eski bir yazı olduğunu biliyorum, ama sadece bunun neden bunu önermediğini merak ettiniz mi? Bu kodda bir sakınca var mı?

+0

eğer "list.Find (x => x.Name ==" yükseklik ")' hiçbir şey döndürmez, hata alıyorum '[NullReferenceException: Nesne başvurusu bir nesnenin örneğine ayarlanmadı.]' –

+0

Her zaman bir null yapabilirsin değeri gerçekten değiştirmeden önce kontrol edin. –

İlgili konular