Ne zaman .First ne zaman ve LINQ ile ne zaman .FirstOrDefault kullanılır?


824

Etrafımda arama yaptım .Firstve ne zaman kullanmak istediğiniz .FirstOrDefaultve LINQ ile ne zaman kullanmak istediğiniz konusunda net bir cevap bulamadım .

  • Ne zaman kullanmak istersiniz .First? Yalnızca sonuç döndürülmediğinde istisnayı yakalamak istediğinizde?

    var result = List.Where(x => x == "foo").First();
  • Ne zaman kullanmak istersiniz .FirstOrDefault? Sonuç yoksa her zaman varsayılan türü ne zaman istiyorsunuz?

    var result = List.Where(x => x == "foo").FirstOrDefault();
  • Ve bu konuda Take'ye ne dersin?

    var result = List.Where(x => x == "foo").Take(1);

86
.Firstve .FirstOrDefaulther ikisi de var result = List.Where(x => x == "foo").First();var result = List.First(x => x == "foo");
tahminleri

59
Düşünmeyi unutmayın Singleve SingleOrDefault. İnsanlar Firstgerçekten kastettiklerinde kullandıklarından nefret ediyorum Single; )
BartoszKP

19
Birden fazla öğe döndürülürse Single veya SingleOrDefault bir istisna atar! Bence FirstOrDefault çoğu durumda daha iyidir!
Eric Draven

21
Önemli olan tek bir sonuç beklediğinizde bunu söylemelisiniz ve istisna mantığınızın başarısız olduğunu gösterir.
NetMage

1
Ayrıca kullanmanın .FirstOrDefault()size her zaman daha anlamlı bir istisna atma fırsatı verdiğini düşünün . Bir sekans istisnası atılırsa ve .First()bir yöntemde birden fazla kural varsa , hangi ifadenin sorun olduğunu anlamak zor olabilir.
StingyJack

Yanıtlar:


807

First()Sıralamanın en az bir elemanı olduğunu bildiğimde veya beklediğimde kullanırım . Başka bir deyişle, sıralamanın boş olması istisnai bir durum olduğunda.

FirstOrDefault()Bir eleman olup olmadığını kontrol etmeniz gerekeceğini bildiğinizde kullanın . Diğer bir deyişle, dizinin boş olması yasal olduğunda. Kontrol için istisna işlemeye güvenmemelisiniz. (Kötü bir uygulamadır ve performansa zarar verebilir).

Son olarak First()ve Take(1)ile arasındaki fark First(), öğenin kendisini Take(1)döndürürken, tam olarak bir öğe içeren bir dizi öğeyi döndürür.


4
@driis - First ve FirstOrDefault arasında seçim yaparken istisnai istisna rehberinin mantrasını kullanabileceğimizi düşünürdüm. Açık cevap için teşekkürler.
Metro Şirin,

5
Ekleyeceğim tek şey, seçtiğiniz tür için varsayılan değer geçerli bir değer olabiliyorsa, örneğin sonucunuz int değeri 0 olabilir, o zaman istisnanın işlenmesi bunu işlemek için en iyi yol gibi görünüyor .
PeterBelm

25
Scratch, bunu başarmak için çok daha güzel bir yol buldum, kullanın: DefaultIfEmpty (-1)
.First

5
Take tam olarak bir öğe döndürmez, en fazla bir öğe döndürür (1 belirtirseniz, elbette). Dizi başlangıçta boşsa, 0 öğe de döndürebilir.
SPIRiT_1984

3
@RoyiNamir, evet alınacak parametrenin 1 olduğu soru bağlamında. Ben de bu cümle hemen sonra parens.
driis

272

.Firstsonuç olmadığında bir istisna atar. .FirstOrDefaultolmazsa, null (başvuru türleri) veya değer türünün varsayılan değerini döndürür. (örneğin 0bir int için olduğu gibi ) Buradaki soru, varsayılan türü istediğinizde değil, daha fazlasındadır: Bir istisnayı mı yoksa varsayılan değeri mi işlemek istersiniz? İstisnalar istisnai FirstOrDefaultolduğundan, sorgunuzdan sonuç elde edip etmeyeceğinizden emin değilseniz tercih edilir. Mantıksal olarak verilerin orada olması gerektiğinde, istisna yönetimi düşünülebilir.

Skip()ve Take()sonuçlarda paging kurarken normalde kullanılır. (İlk 10 sonucu, sonraki sayfada sonraki 10 sonucunu göstermek gibi)

Bu yardımcı olur umarım.


5
@Jeroen - Skip / Take kullanmak için daha iyi kullanım durumları için iyi bir nokta.
Metro Şirin,

4
.FirstOrDefaultReferans türleri için null değerini döndürecek açıklama için +1 . "Varsayılan" bir nesnenin ne olacağı konusunda kafam karışmıştı. Bu cevap bunu açıklığa kavuşturdu.
Mike Taverne

115

.First()döndürülecek satır yoksa bir istisna atar, bunun yerine .FirstOrDefault()varsayılan değeri ( NULLtüm referans türleri için) döndürür .

Bu nedenle, olası bir istisnayı ele almaya hazırsanız ve istekliyseniz .First(), sorun değil. != nullYine de dönüş değerini kontrol etmeyi tercih ederseniz , daha .FirstOrDefault()iyi bir seçimdir.

Ama sanırım bu biraz kişisel bir tercih. Sizin için daha anlamlı ve kodlama stilinize daha uygun olanı kullanın.


66

İlk()

  1. Bir dizinin ilk öğesini döndürür.
  2. Sonuçta hiçbir öğe yoksa veya kaynak null olduğunda hata atar.
  3. Birden fazla öğe bekleniyorsa ve yalnızca ilk öğe istiyorsanız bunu kullanmalısınız.

FirstOrDefault ()

  1. Bir dizinin ilk öğesini veya öğe bulunmazsa varsayılan değeri döndürür.
  2. Yalnızca kaynak boşsa bir hata atar.
  3. Birden fazla öğe bekleniyorsa ve yalnızca ilk öğe istiyorsanız bunu kullanmalısınız. Sonuç boşsa da iyi.

Aşağıda gösterildiği gibi bazı kayıtları olan bir UserInfos tablonuz var. Aşağıdaki bu tabloya dayanarak örnek oluşturdum ...

UserInfo Tablosu

İlk () nasıl kullanılır

var result = dc.UserInfos.First(x => x.ID == 1);

ID == 1 olduğu tek bir kayıt var. Bu kayıt
kimliğini döndürmelidir ID: 1 Adı: Manish Soyadı: Dubey E-posta: xyz@xyz.com

var result = dc.UserInfos.First(x => x.FName == "Rahul");   

FName == "Rahul" olduğunda birden fazla kayıt vardır. İlk kayıt iade edilmelidir.
ID: 7 Adı: Rahul Soyadı: Sharma E-posta: xyz1@xyz.com

var result = dc.UserInfos.First(x => x.ID ==13);

ID == 13 olan bir kayıt yok. Bir hata oluşmalıdır.
InvalidOperationException: Sekans öğe içermiyor

FirstOrDefault () Nasıl Kullanılır

var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);

ID == 1 olduğu tek bir kayıt var. Bu kayıt
kimliğini döndürmelidir ID: 1 Adı: Manish Soyadı: Dubey E-posta: xyz@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");

FName == "Rahul" olduğunda birden fazla kayıt vardır. İlk kayıt iade edilmelidir.
ID: 7 Adı: Rahul Soyadı: Sharma E-posta: xyz1@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);

ID == 13 olan bir kayıt yok. Dönüş değeri null

Umarım ne zaman kullanılacağını anlamanıza yardımcı olur First()veya FirstOrDefault().


4
Bence, "Bir hata oluşmalıdır" ifadesi. Üçüncü FirstOrDefault () altında - örnek yanıltıcıdır.
Jannik

Merhaba, iyi açıklıyorsunuz, ancak birleştirme işleminden veri alındığında ve kimlik o sırada kullanılan yabancı anahtar tablosunda olmadığında biraz kafam karıştı? Şu anda, First () kullanıyorum ama cevabınızı okuduktan sonra hiçbir fikrim yok.Lütfen yardım edin
Brijesh Mavani

20

Her şeyden önce, Taketamamen farklı bir yöntemdir. IEnumerable<T>Tek değil, bir döndürür T, bu yüzden dışarıda.

Arasında Firstve FirstOrDefault, kullanmak gerekir FirstEğer bir eleman varsa ve bunları yapmazsa, o zaman bir hata olmadığına emin olduğunuzda.

Bu arada, diziniz default(T)öğeler (örn. null) İçeriyorsa ve boş ve ilk öğe arasında ayrım yapmanız gerekiyorsa null, kullanamazsınız FirstOrDefault.


2
@Mehrdad - büyük puan, yeniden: .İlk IEnumerable ve ne zaman FirstOrDefault kullanılmaz döndürür.
Metro Şirin,

15

İlk:

  • Bir dizinin ilk öğesini döndürür
  • Atma istisnası: Sonuçta hiçbir öğe yok
  • Şu durumda kullanın: 1'den fazla öğe bekleniyorsa ve yalnızca ilk öğe istediğinizde

FirstOrDefault:

  • Bir dizinin ilk öğesini veya öğe bulunamazsa varsayılan değeri döndürür
  • İstisna atar: Yalnızca kaynak boşsa
  • Şu durumda kullanın: 1'den fazla öğe bekleniyorsa ve yalnızca ilkini istediğinizde. Ayrıca sonucun boş olması da sorun değil

Gönderen: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/


10

Dikkat edilmesi gereken bir diğer fark, bir Üretim ortamında bir uygulamada hata ayıklamak durumunda satır numaralarına erişemeyebilirsiniz, bu nedenle .First()bir yöntemdeki özel ifadenin istisnayı attığının belirlenmesi zor olabilir.

İstisna mesajı, herhangi bir problemin hata ayıklamasını bile zorlaştıracak, kullandığınız herhangi bir Lambda ifadesini içermeyecektir.

Bu nedenle FirstOrDefault(), boş bir girişin istisnai bir durum olacağını bilsem de her zaman kullanıyorum .

var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
   throw new Exception(string.Format("Can't find customer {0}.", customerId));
}

5

İlk()

Bu sonucun 1'den fazla eleman beklediğini bildiğinizde ve sadece dizinin ilk elemanı olmalıdır.

FirstOrDefault ()

FirstOrDefault () tıpkı First () gibidir, ancak belirtilen koşulla eşleşen hiçbir öğe, altta yatan genel koleksiyon türünün varsayılan değerini döndürür. Hiçbir öğe bulunamazsa InvalidOperationException öğesini atmaz. Ancak elemanın veya bir dizinin toplanması, bir istisna attığından daha sıfırdır.


Merhaba, iyi açıklıyorsunuz, ancak birleştirme işleminden veri alındığında ve kimlik o sırada kullanılan yabancı anahtar tablosunda olmadığında biraz kafam karıştı? Şu anda, First () kullanıyorum ama cevabınızı okuduktan sonra hiçbir fikrim yok.Lütfen yardım edin
Brijesh Mavani

4

Bu fonksiyon türü eleman operatörlerine aittir. Bazı yararlı eleman operatörleri aşağıda tanımlanmıştır.

  1. İlk / FirstOrDefault
  2. Son / LastOrDefault
  3. Tek / SingleOrDefault

Belli bir koşula bağlı olarak bir sekanstan tek bir eleman seçmemiz gerektiğinde eleman operatörlerini kullanıyoruz. İşte bir örnek.

  List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };

First () operatörü, koşul yerine getirildikten sonra dizinin ilk öğesini döndürür. Hiçbir öğe bulunamazsa, bir istisna atar.

int sonuç = öğeler. Nerede (item => item == 2) .First ();

FirstOrDefault () operatörü, koşul yerine getirildikten sonra dizinin ilk öğesini döndürür. Hiçbir öğe bulunamazsa, o türün varsayılan değerini döndürür.

int sonuç1 = öğeler.Nerede (item => item == 2) .FirstOrDefault ();


güzel anlaşılması kolay bir örnek ile açıkladı.
Arslan Bhatti


2
someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)

Hangisini kullanmalıyım? İstisna / program başarısızlığı korkusu değil, iş mantığı tarafından karar verilmelidir.

Örneğin, iş mantığı herhangi bir iş gününde sıfır işlem yapamayacağımızı söylüyorsa (Sadece varsayalım). O zaman bu senaryoyu bazı akıllı programlamalarla ele almaya çalışmamalısınız. Ben her zaman böyle bir koleksiyon üzerinde First () kullanacağım ve başka bir şey iş mantığını çürütürse programın başarısız olmasına izin vereceğim.

Kod:

var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()

Başkalarının bu konudaki yorumlarını görmek istiyorum.


Başvuru ve boş değer türleri için varsayılan değer null değeridir.
dsa

Hızlı bir şekilde başarısız olmak iyidir - ancak tanımladığınız senaryo için İlk önce başarısız olsun, istisnayı yakalayın ve sonra anlamlı bir hata döndürmeyi tercih ederim. Catch (InvalidOperationException e) {gibi yeni InvalidOperationException ("Günde sıfır işlem yapılamaz!", E)}; Ama evet, gerçek bir iş mantığı sorunuyla uğraşmaktan kaçınmak için varsayılanı kullanmak çok kötü.
Mathieson

1

Tamam, iki sentimi vermeme izin ver. İlk / Firstordefault, ikinci yapıcıyı kullandığınız zaman içindir. Ne olduğunu açıklamayacağım, ancak potansiyel olarak her zaman kullanacağınız zamandır, çünkü bir istisna oluşturmak istemezsiniz.

person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
    return string.IsNullOrEmpty(p.Relationship);
}));

Tam olarak değil. İlk kurucu, yalnızca bir öğe almanız gerektiğinde veya sonucu bir dizi olmayan bir değere atarken derleme hatasından kaçınmanız gerektiğinde yaygın olarak kullanılır ve sorgunun tam olarak bir sonuç döndürdüğünden emin olabilirsiniz. Ek bir .Where () kullanmak yerine ikinci yapıcıyı kullanmak daha hızlı görünse de (
LINQ'nun

0

Diğerleri First()ve arasındaki farkı çok iyi tanımladılar FirstOrDefault(). Bu yöntemlerin anlambilimini yorumlamak için yeni bir adım atmak istiyorum. Bence FirstOrDefaultçok fazla kullanılıyor. Verileri filtrelediğiniz çoğu durumda, mantıksal koşulla eşleşen bir öğe koleksiyonunu veya benzersiz bir tanımlayıcıyla (kullanıcı, kitap, posta vb. Gibi) tek bir benzersiz öğeyi geri almayı beklersiniz. neden FirstOrDefault()bir kod kokusu olduğunu söyleyebiliriz ki, yanlış bir şey olduğu için değil, çok sık kullanıldığı için. Bu blog gönderisi konuyu ayrıntılı olarak araştırıyor. Çoğu zaman IMOSingleOrDefault() çok daha iyi bir alternatiftir, bu nedenle bu hataya dikkat edin ve sözleşmenizi ve beklentilerinizi açıkça gösteren en uygun yöntemi kullandığınızdan emin olun.


-6

linq koleksiyonlar üzerinde tek bir basit sorgu uygulamak için birçok yolu, sadece sql birleştirme yazmak, bir filtre ilk veya son uygulanabilir ihtiyaca ve ihtiyacına bağlı olarak.

İşte koleksiyonda kimliğine sahip bir öğe bulabileceğimiz bir örnek. Buna daha fazlasını eklemek için, ilk olarak, FirstOrDefaultbir koleksiyonun en az bir kaydı olduğunda ideal olarak aynı şekilde dönecektir. Bununla birlikte, bir koleksiyonun boş olması uygunsa. sonra Firstbir istisna döndürür ancak FirstOrDefaultdöndürür nullveya varsayılan değer döndürür . Örneğin, int0 döndürür. Bu nedenle, bu tür kullanımın kişisel tercih olduğu söylenir, ancak FirstOrDefaultistisna işlemeyi önlemek için kullanılması daha iyidir . burada bir işlem listesi koleksiyonu üzerinden çalıştığımız bir örnek var

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.