.Any () 'in C # List <> içindeki kullanımı nedir?


40

Bunu meslektaşlarımla tartışıyordum ve C # ' .Anyda verilen herhangi bir kullanımın ne olduğunu bulamadık List<>.

Dizideki bir öğenin geçerliliğini aşağıdaki ifade gibi kontrol edebilirsiniz:

if (MyList.Any()){ ...}  //Returns true or false

Tam olarak aynı olan

if (MyList.Count() != 0) { ... }

ve ififadenin amacı hakkında çok daha yaygın, okunaklı ve açıktır .

Sonunda, bu düşünce ile sıkışıp kaldık:

.Any() kullanılabilir, aynı şekilde çalışır, ancak programcının amacına dair daha az açıktır ve bu kullanılmamalıdır.

Ancak bunun doğru olamayacağını düşünüyoruz; bir şeyleri özlüyor olmamız gerekiyor.

Biz?


40
Neye göre daha az net bir şekilde?
jk.

35
Daha Any()az açık olan iddianıza meydan okuyorum: Any()özellikle bir lambda koşulu ile bana daha açık görünüyor. Kafamdaki İngilizce'ye kod çevirme, if(MyList.Count(o => o > 10) > 0)olur "10 den fazla 0'dan öğe sayısı yüksek mi?" oysa if(MyList.Any(o => o > 10))olur "Orada herhangi ürün 10 üzerinde mi?"
BlueRaja - Danny Pflughoeft 4:15

3
@SargeBorsch - yalnızca çoğu insanın yapmadığı Heskel / fonksiyonel adlandırma tercih ederseniz.
Davor Ždralo

4
@ BlueRaja-DannyPflughoeft katılıyorum. Herhangi birinin daha açık olduğunu düşünüyorum, çünkü sihirli sayı olarak kabul edilebilecek bir şeyi ortadan kaldırır.
Andy,

2
@SargeBorsch: SQL paralel AnyDİR Exists. Linq ismi muhtemelen Haskell ve Python'dan esinlenerek, hepsinde / hepsinde fonksiyonlara sahip.
JacquesB

Yanıtlar:


95

Üzerinde Anyçalışmayan bir akılda tutmak List; mülkiyeti olan IEnumerableveya olmayan bir somut tipi temsil eden bir üzerinde çalışır Count. Bu mutlaka bir kullanım için en iyi şey olması gerektiği doğru değil List, ancak kesinlikle bir LINQ sorgusu sonunda kullanışlı olur. Ve bağımsız sürümden bile daha kullanışlı olması, tıpkı aynen böyle bir kehanette bulunmakta olan geçersiz kılmadır Where. ListYerleşik Anyeklenti yöntemi kadar elverişli ya da etkileyici olan herhangi bir yerde yerleşik hiçbir şey yoktur .

Ayrıca, (özellik açık ) Count()yerine Count( IEnumerable için LINQ uzantı yöntemi) kullanıyorsanız, altta yatan veri türünüzün bir Özelliği olduğunu tespit ederek bunu en iyi durumaList getiremiyorsa, tüm diziyi numaralandırması gerekebilir. . Uzun bir dizilişiniz varsa, bu sayımın ne olduğunu gerçekten umursamadığınızda ve sadece koleksiyonda herhangi bir öğe olup olmadığını bilmek istediğinizde göze çarpan bir performans kazancı olabilir .Count


19
Bu. Performansı bir yana bırakmak ile, Any()bir kestirmek, bunun geçersiz kılma değerini 0 ile karşılaştırmaktan daha Enumerable.Count()
Dan J

1
Bence bu, temelleri çok net bir şekilde açıklıyor ve cevabı en iyi şekilde açıklıyor.
Tarik

2
IMHO, bir tahminde bulunmak Existskadar rahat ve etkileyici Any. A Count != 0özelliğini kullanmak , kullanmaktan Listdaha normaldir Any(). Bu sadece kişisel bir tercih. Ben de değişen çaba geçtiniz _list_.Count()için _list_.Countbenim grubun kodunda. Benim için gözle görülür bir fark yarattı.
Suncat2000

55

Bir çalışma süresi farkı Count(), O (n) Any(), O (1) olabilir.


15
Count()Sonsuz yineleyiciler için de durmayacak Any(), sadece bir MoveNext()kez çağırması gerektiği için olacaktır .
Jon Purdy

3
Özlü ve doğru, ama bu bir cevaptan çok bir yorum olarak okuyor. Programcılar, nedenini açıklayan ve bir açıklama ölçüsü sağlayan cevapları tercih eder . Cevabınızı düzenleyerek ve O (1) 'in neden önemli olduğu konusunda genişlemeyi düşünün .

çok iyi bir cevap sadece saymak yerine herhangi bir şey kullanmam gerektiğini öğrendim == 0: d
MonsterMMORPG

4
Any(Func<T>)O (n)
BlueRaja - Danny Pflughoeft

1
Belirli bir durumda List, uzantı özelliği kullandığından performans aynıdır. ICollectionArabirimi uygulayan tüm koleksiyonlar için geçerlidir .
Thorkil Holm-Jacobsen,

9

Aslında, List.Count özelliği olduğunu ve ardından Enumerable.Count yönteminin bulunduğunu unutmayın.

Örnekte, Enumerable.Count()bir sonuç döndürmek için numaralandırmanın her bir öğesinde yineleme yapmak zorunda olan yöntemi kullanıyorsunuz . Bu, Any()yalnızca varsa, ilk öğenin üzerinde yineleme ihtiyacı duyan aramadan açıkça yavaştır .

DÜZENLE:

Yorumlarda, doğru olarak belirtildi, böylece, Enumerable.Count()numaralandırılabilirin aynı zamanda olduğunu tespit ederse, uzatma yönteminin tüm öğeleri yinelemesine gerek kalmadı ICollection<T>. Öyleyse, a ' List<T>nın Countözelliğini ya da yöntemi kullanmak aslında bir fark yaratmaz.

IEnumerable.Count kaynak:

public static int Count<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) return collectionoft.Count;
    ICollection collection = source as ICollection;
    if (collection != null) return collection.Count;
    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        checked {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}

Yeterince adil. Peki ya .Count özelliğinin kullanımı? bu, okumayı önemli ölçüde daha hızlı yapmaz mıydı, belki de çağırmaktan daha hızlı, hatta daha hızlı.
Gil Sand

4
Bir List<T>performans farkı ile önemsiz olacak. Yani sadece ne istersen onu kullan. Ancak, diğer IEnumerable türleri için, yalnızca Count()(yöntem) arasında seçim yaparsınız Any()ve bu durumda, Any()kullanım durumunuz için daima açık kazanan olur ve tercih edilmelidir. Buna değer, bence Any()oldukça okunaklı ve net.
sstan

eğer sayılabilir eğer bir koleksiyona atılamazsa, o zaman optimize edilebilir ve önemli olmaz.
Esben Skov Pedersen

2
Count()aynı karmaşıklığı Countiçin ICollectionuzatma yöntemi daha sonra iterating yerine özelliğini kullanır çünkü, s.
Thorkil Holm-Jacobsen,

Linq uzantıları bilinen arayüzler için optimize edilmiştir - IList, ICollection. Buradaki performans tartışması, bu bir uygulama detayı olsa bile, tamamen gereksizdir
Gusdor

6

Şaşırtıcı bir soru - niyetinden list.Any()çok daha net olma niyetini buluyorum list.Count()!=0.

Amaç şu anlama gelir: Eğer birisinin kodunu okursanız (ve kendiniz yazmamışsanız), programcının neyi başarmak istediği ve neden böyle yazıldığının açık bir ifadesi var mı? Yaygın bir problem gereksiz yere karmaşık bir şekilde çözülürse, derhal şüphelenirsiniz ve geliştiricinin neden basit yolu kullanmadığını merak edersiniz. Kodun içine bakarsınız ve bir şeyleri kaçırıp kaçırmadığınızı görmeye çalışırsınız. Kodu değiştirmekten korkuyorsunuz, çünkü kaçırdığınız bazı yan etkiler olduğundan endişeleniyorsunuz ve değiştirmek beklenmedik sorunlara neden olabilir.

Any()Yöntemi kullanmanın amacı tamamen açık - listede herhangi bir eleman olup olmadığını bilmek istiyorsunuz.

Count()!=0Öte yandan ifadenin amacı okuyucu için açık değildir. Elbette, ifadenin listenin boş olup olmadığını söylediğini görmek zor değil. Sorular, standart yöntemi kullanmak yerine, bunu bu şekilde yazmanızdan kaynaklanmaktadır. Neden Count()açıkça kullanıyorsunuz? Bir listede gerçekten bir eleman olup olmadığını bilmeniz gerekiyorsa , neden önce tüm listeyi saymak istiyorsunuz? 1'e ulaştığınız anda, cevabınızı zaten aldınız. Eğer kaynak büyük (belki de sonsuz) bir koleksiyonun üzerinde bir yineleyiciyse veya sql'ye çevrilmişse, akıllıca büyük bir fark yaratabilir. Öyleyse belki de Count () kullanımı açıkça ertelenmiş bir sorguyu bir yineleyiciyi çalıştırmaya veya geçmeye zorlamakta mıdır?

Ancak kaynak aslında olup List<T>burada Count()O (1) ve bir yan etkisi yoktur. Ancak, kod bu özelliğe dayanıyorsa, List<T>neden Counthiç bir yan etkisi olmadan bir O (1) işlemi beklediğinizi belirten -çayılılığı kullanmıyorsunuz?

Yazılmış olduğu gibi, list.Count()!=0aynı aynen yapar list.Any()o gereksiz yere daha karmaşıktır ve niyet belli değildir hariç.


Her ikisini de "Listede herhangi bir öğe var mı?" Olarak okudum. Count()kullanmaktan kaçınmam gereken zımni bir çevrimi var, ancak belirsiz değil. Derleyici onu en iyi duruma getirebilir ve bu da yalnızca dikkatsiz kodlamayı sağlar.
Suncat2000

2

Belki de sadece kelimedir? AnyBir sıfat, gerçekten bir şey söylemiyor. Java dan geliyorsa, ben isNonEmptybir fiil içeren denir. Bir SQL adamı tercih edebilir EXISTS. Fakat belki Anyde C # sistemine en iyi şekilde uyar.

Kelime seçimi ne olursa olsun, alıştıktan sonra, daha net olmalı . " more than zeroBira şişesi kalmış mı" diye sorar mısın ? one or moreİnsanların "Hayır, yok" yanıtını vermeden önce onları saymaya başlamasını bekler misiniz any?


1
LINQ açısından düşündüğünüzde "herhangi bir" adı Any()gerçekten bir anlam ifade eder: gerçekten bir kısayoldurAny(o => true)
BlueRaja - Danny Pflughoeft

Normalde, bir numaralandırıcının numaralandırmak için herhangi bir engelinin olup olmadığını açıklamak için boş kullanmazdım. Ama " numaralandırılacak bir şey var mı" bana göre doğal görünüyor ve herhangi bir numaralandırmaya karşı herhangi bir çalışma.
Andy
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.