LINQ sorgularında seçimler yaparken Single, SingleOrDefault, First ve FirstOrDefault extension metodları sık sık başvurulan metodlardır. Bu metodları kullanırken bazen beklenmeyen durumlarla karşılaşabiliriz. Bu metodlar arasındaki farkları bildiğimiz taktirde istenmeyen durumlardan da kurtulmuş oluruz.
Şimdi “Single ve SingleOrDefault arasındaki fark nedir?” ve aynı şekilde “First ve FirstOrDefault arasındaki fark nedir?” sorularının cevabını aramaya çalışalım.
Tek rakamları içeren int tipinde bir dizimiz olduğunu varsayalım. Bu diziden herhangi bir teksayıyı seçmek istediğimizde hangi durumda hangi sorguyu kullanmalıyız?
int[] oddNumbers = { 1, 3, 5, 7, 9 };
SingleOrDefault: Eğer dizi içinden sadece bir tane sayı seçmek istiyorsak ve seçim şartımız sağlanmıyorsa, bu durumda int tipinin varsayılan değeri olan 0(sıfır) döndürülsün istiyorsak SingleOrDefault seçimini kullanmalıyız.
int[] oddNumbers = { 1, 3, 5, 7, 9 }; int number = oddNumbers.SingleOrDefault(n => n.Equals(4)); Console.WriteLine(number);
Yukarda görüldüğü üzere dizi içerisinde 4 değeri olmadığı için program çıktısı 0 olacaktır.
Eğer seçim sonucunda birden fazla değer dönerse InvalidOperationException fırlatılacaktır.
int[] oddNumbers = { 1, 3, 5, 7, 9 }; int number = oddNumbers.SingleOrDefault(n => n > 1); Console.WriteLine(number);
Yukarıdaki kod parçası hata fırlatılacaktır. Çünkü 1’den büyük olan, birden fazla eleman vardır.
Single: Eğer seçimimiz sonucunda sadece bir tane eleman geleceği garanti ise, bu durumda Single seçimini kullanabiliriz. Eğer şartımızı sağlayan hiçbir eleman dönmezse veya şartımızı sağlayan birden fazla eleman dönerse, bu iki durumda da istisnalar fırlatılacak ve hata ile karşılaşmış olacağız.
int[] oddNumbers = { 1, 3, 5, 7, 9 }; int number = oddNumbers.Single(n => n.Equals(3)); Console.WriteLine(number);
Yukarıdaki örnekte şartımız sağlandığı için 3 sonucu çıktı olarak gösterilecektir.
int[] oddNumbers = { 1, 3, 5, 7, 9 }; int number = oddNumbers.Single(n => n.Equals(2)); Console.WriteLine(number);
Yukarıdaki örnekte ise 2’ye eşit olan herhangi bir eleman olmadığı için InvalidOperationException istisnası fırlatılacaktır.
FirstOrDefault: Bu seçimde de mantık SingleOrDefault ile aynıdır. Ancak bu seçimde istenen şartta ilk eleman seçilir. Örneğin dizinin ilk elemanı, dizinin 2’den büyük ilk elemanı gibi.
First: Mantık Single ile aynıdır, ancak seçilen ilk elemandır.
int[] oddNumbers = { 1, 3, 5, 7, 9 }; int number = 0; number = oddNumbers.FirstOrDefault(n => n > 9); // Sonuç: 0 number = oddNumbers.FirstOrDefault(n => n == 3); // Sonuç: 3 number = oddNumbers.First(n => n == 5); // Sonuç: 5 number = oddNumbers.First(n => n > 2); // Sonuç: 3 number = oddNumbers.First(n => n > 9); // Sonuç: HATA Console.WriteLine(number);
Umarım faydalı olmuştur. Tekrar görüşmek üzere.
iyi çalışmalar bu konu üzerine bir sorum olacak. firstordefault şartı ile çektiğimizde gelen deperi atadığımız gelen class türünden Deger isminde class örneğine null gelebiliyor. eğer dediğiniz gibi olsa bu değerin null değil o classın default değerlerle doldurulmuş bir örneği gerekmez mi?
cevabınızı mail olarak da alabilirsem çok sevinirim..
iyi çalışmalar…
FirstOrDefault der ki eğer bir tipin varsayılan değeri(default) varsa onu veririm. Örneğin int, double gibi tiplerin varsayılan değeri vardır ve 0’dır. Eğer varsayılan değer de yoksa null döndürmek zorundadır. Sizin dediğiniz şekilde bir sınıfın oluşturulmuş nesne örneği verilecek olsa zaten ismi FirstOrDefaultOrObject gibi birşey olurdu. Sizin bahsetmek istediğiniz de zaten FirstOrDefault sonucunda bir sonuç bulunamaz ise new MyClass() şeklinde bir sonucun bize verilmesi ve exception almamaktır anladığım kadarıyla. Ama dediğim gibi aranan sonuç bulunamaz ise Null verir.
Harika süper bir makale