2012-02-17 26 views
96

Sık sık Where.FirstOrDefault() numaralı telefonu kullanarak arama yaparak ilk öğeyi yakalarım. Neden sadece Find() kullanıyorsunuz? Diğeri için bir avantaj var mı? Bir fark anlayamadım. IEnumerable<T> üzerinde Find yöntem NeredeFind() vs. Where() FirstOrDefault()

namespace LinqFindVsWhere 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<string> list = new List<string>(); 
      list.AddRange(new string[] 
      { 
       "item1", 
       "item2", 
       "item3", 
       "item4" 
      }); 

      string item2 = list.Find(x => x == "item2"); 
      Console.WriteLine(item2 == null ? "not found" : "found"); 
      string item3 = list.Where(x => x == "item3").FirstOrDefault(); 
      Console.WriteLine(item3 == null ? "not found" : "found"); 
      Console.ReadKey(); 
     } 
    } 
} 
+33

FWIW, 'list.FirstOrDefault (x => x ==" item3 ");' '.Where' ve' .FirstOrDefault' öğelerinin her ikisini de kullanmaktan daha özlüdür. –

+0

@Kirk, sanırım bir sonraki sorum, niçin bulmayı da eklediler. Bu iyi bir ipucu. Düşünebildiğim tek şey, FirstOrDefault öğesinin boş değerden farklı bir varsayılan değer döndürmesidir. Aksi takdirde sadece anlamsız bir ekleme gibi görünüyor. – KingOfHypocrites

+6

'Bul, LINQ’yi önceden seçiyor. (.NET 2.0'da mevcuttu ve lambda'ları kullanamıyordunuz. Normal yöntemler veya anonim yöntemler kullanmaya zorlandınız) –

cevap

138

mı? (Retorik bir soru.) Where ve FirstOrDefault yöntemler bu yöntemleri kullanabilir IEnumerable<T> uygulayan List<T>, T[], Collection<T>, vb herhangi bir sekansı da dahil olmak üzere birçok sekans türlü karşı uygulanabilir

. Find yalnızca List<T> için kullanılabilir. Genellikle daha uygulanabilir yöntemler, daha fazla yeniden kullanılabilir ve daha büyük bir etkiye sahip.

Sanırım bir sonraki sorum, niçin bulmayı da eklediler. Bu iyi bir ipucu. Düşünebildiğim tek şey, FirstOrDefault öğesinin boş değerden farklı bir varsayılan değer döndürmesidir. Aksi takdirde sadece List<T> üzerinde

Find diğer yöntemleri önceleyen bir anlamsız ek benziyor. List<T>, .NET 2.0'da generics ile eklenmiştir ve Find, bu sınıfın API'sinin bir parçasıydı. Where ve FirstOrDefault, daha sonra .NET sürümü olan Linq ile IEnumerable<T> için uzantı yöntemleri olarak eklenmiştir. Linq, Find'un hiçbir zaman eklenmeyeceği 2.0 sürümü ile mevcut olsaydı, ancak daha önceki sürümlerde eski veya eski haline getirilmiş olan daha önceki .NET sürümlerinde ortaya çıkan diğer pek çok özellik için de geçerli olduğunu söyleyemem.

+0

Mükemmel cevap. Teşekkür ederim. – KingOfHypocrites

+50

Sadece tamamlayıcı: Nerede ve İlk veya FirstOrDefault çağrılmaya gerek yoktur: First veya FirstOrDefault, bir arama yüklemesi belirtmenize izin verir, bu, nerededir, aramayı gereksiz yapar –

22

Find, List<T> sadece implemented tüm IEnumerable<T> ile Where().FirstOrDefault() eser ise.

34

Bugün sadece 80K nesnelerin bir listesi üzerinde bazı testler yaptım ve Find()'un Where'u FirstOrDefault() ile kullanmaktan% 1000 daha hızlı olabileceğini öğrendim. Her zaman önce ve sonra bir zamanlayıcıyı test etmeden önce bunu bilmiyordum. Bazen aynı zamanda oldu, aksi halde daha hızlıydı.

+5

Nerede ve FirstOrDefault ile denediniz mi? Eğer yaptıysanız belki de sadece FirstOrDefault ile deneyin ve Find() 'ın hala daha iyi olup olmadığını görün. – MVCKarl

+1

@MVCKarl lütfen [buraya] bakın (http://stackoverflow.com/questions/14032709/performance-of-find-vs-firstordefault). Bul, neredeyse iki kat daha hızlıdır.Ama bunu anlayamıyorum, çünkü hiçbir Enumerator yokluğu yüzünden mi? –

+3

Gerçekten de sorguyu gerçekleştirmek için sonucu '.ToList()' veya '.ToArray()' ile sonuçlandırmamışsınız gibi geliyor. –

12

Verilerin kaynağının Varlık Çerçevesi olması durumunda çok önemli bir fark vardır: Find, 'artık' durumundaki varlıkları henüz kalıcı değil, ancak Where kullanmayacaktır. Bu tasarım gereğidir.