Herhangi bir () * değil * 'in boş bir başvuru istisnası atmasını beklemenin mantıksızlığı var mı?


41

Eğer yapabilirsiniz uzatma yöntemini oluştururken, tabii ki, üzerinde çağrı nullgelmez boş üzerinde çağıran bir örnek yöntemi çağrısı aksine .ama sahip bir atmak NullReferenceException-> kontrol etmek ve elle atmak zorunda.

Linq uzatma yönteminin uygulanması için Any()Microsoft, bir tane atmaları gerektiğine karar verdi ArgumentNullException( https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/AnyAll.cs ).

Yazmak zorunda olmam beni rahatsız ediyor if( myCollection != null && myCollection.Any() )

Yanlış mıyım, bu kodun bir müşterisi olarak, örneğin ((int[])null).Any()geri dönmesi beklenmeli falsemi?


40
C # 6'da, sen eğer için çekinizi kolaylaştırabilirsiniz (myCollection == true yapacağı her türlü ()?)
17 26

5
Diğer .NET dilleriyle birlikte çalışabilirlik dışında gerçekten boş değer kullanmayan F # 'da bile null |> Seq.isEmptyfırlatır System.ArgumentNullException: Value cannot be null. Beklenti, var olması beklenen bir şey için tanımsız değerleri geçmeyeceğiniz gibi görünüyor, bu nedenle boş bir durum olduğunda hala bir istisnadır. Bu bir başlangıç ​​sorunuysa, a yerine boş bir sekansla başlarım null.
Aaron M. Eshbach

21
Bu yüzden nullkoleksiyonlarla uğraşırken geri dönmemelisin , fakat bu durumlarda boş bir koleksiyon kullanmalısın.
Bakuriu

31
Peki neden ilk boş? Boş olarak sayılmak istemezsiniz, çünkü boş değildir, tamamen farklı bir şeydir. Belki de sizin durumunuzda boş sayılmasını istiyorsunuz, fakat dile bu tür bir şey eklemek hatalara yol açıyor.
user253751

22
Her LINQ yönteminin boş bir argümanla başladığını belirtmeliyim . Anysadece tutarlı.
Sebastian Redl

Yanıtlar:


157

İçinde beş tane patates bulunan bir çantam var. .Any()Çantada patates var mı?

" Evet " diyorsun.<= true

Bütün patatesleri alıp yerim. .Any()Çantada patates var mı?

" Hayır " diyorsun.<= false

Çantayı tamamen ateşte yakıyorum. .Any()Çantada patates var mı?

" Çanta yok ."<= ArgumentNullException


3
Ama boşal, torbada patates yok mu? Yanlış, Yanlış anlamına gelir ... (katılmıyorum, sadece ikinci bir bakış açısı).
D. Ben Knoble 21:18

6
daha pratik olarak, birisi size bilinmeyen bir kaynaktan kapalı bir kutu verir. Kutudaki çantada patates var mı? Sadece 2 senaryo ile ilgileniyorum - A) Kutuda patates bulunan bir çanta var ya da B) Kutuda patates ve / veya torba yok. Anlamsal olarak, evet, boş ve boş arasında bir fark var, ama zamanımın% 99'u umrumda değil.
dave thieben 21:18

6
Beş çiğ patates yedin mi? Derhal tıbbi yardım alın.
Oly

3
@Oly Dan, çantayı yakmak için o yangını yemeden ve kullanmadan önce onları ateşte pişirdi.
Ismael Miguel,

3
@ D.BenKnoble: Arabamın bagajını görmeden arabamın bagajında ​​hiç ceset olmadığını belirtmeye istekli misiniz? Hayır? Bagajı kontrol etmekle hiçbir şey bulamamak ya da bagajı kontrol etmemek arasındaki fark nedir? Her iki durumda da aynı miktarda cesedi gördüğünüz için, şimdi tanıklık edemez misiniz? ... Bu fark. İlk başta doğrulayamıyorsanız, bir şey için garanti veremezsiniz. İkisinin eşit olduğunu varsayıyorsunuz, ama bu verilen bir şey değil. Bazı durumlarda, ikisi arasında önemli bir fark olabilir.
Flater

52

Öncelikle, kaynak kodu atmak edeceği anlaşılmaktadır ArgumentNullExceptiondeğil NullReferenceException.

Diyelim ki, çoğu durumda koleksiyonunuzun null olmadığını zaten biliyorsunuzdur, çünkü bu kod yalnızca koleksiyonun zaten var olduğunu bilen koddan çağrılır, bu nedenle null kontrolünü oraya sık sık koymak zorunda kalmazsınız. Ancak var olduğunu bilmiyorsanız, çağırmadan önce kontrol etmeniz mantıklı olacaktır Any().

Yanlış mıyım, bu kodun bir müşterisi olarak, örneğin ((int[])null).Any()geri dönmesi beklenmeli falsemi?

Evet. Bu sorunun Any()cevabı "Bu koleksiyon herhangi bir unsur içeriyor mu?" Bu koleksiyon mevcut değilse, sorunun kendisi saçmadır; hiçbir şey içeremez veya içeremez, çünkü yoktur.


18
@ ChrisWohlert: Sezginiz beni merak ediyor. Ayrıca anlamsal olarak var olmayan bir kişinin boş bir kişi olduğunu mu düşünüyorsunuz, adı boş dize ve yaşı sıfır vb. Ve içeren nullbir kümenin boş kümeyi içeren kümeye eşdeğer olduğunu mu düşünüyorsunuz (ve tersi)?
18:18

17
@ ChrisWohlert: Açıkçası bir küme boş kümeyi içerebilir; ama buna inanıyor görünüyorsun { null }ve { {} }eşdeğer olmalısın. Bunu büyüleyici buluyorum; Bununla hiç ilişki kuramıyorum.
eylül

9
.AddBir nullkoleksiyonda bir şekilde bizim için de bir koleksiyon oluşturmalı mıyız ?
Matthew

13
@ChrisWohlert "Bir boş bir kümesidir B karpuz içeren bir dizi Is A boşaltmak Evet Is B boşaltmak sayılı Is C boşaltın Uhhh .....?.?"
user253751

16
Pedantik nokta: Küme teorisinde var olmayan bir kümenin boş bir küme olması durum değildir. Boş küme var ve var olmayan herhangi bir küme o değil (ve aslında hiç olmadığı için hiçbir şey değil).
James_pic

22

Boş (Null) eksik bilgi demektir, eleman yok.

Boş değerden kaçınmayı daha geniş çapta düşünebilirsiniz - örneğin, boş yerine numaralandırılmamış bir koleksiyonu temsil etmek için boş boş numaralandırıcılardan birini kullanın.

Bazı durumlarda null değerine geri dönüyorsanız, boş koleksiyonu geri döndürmek için bunu değiştirebilirsiniz. (Aksi takdirde, null'un kütüphane yöntemleriyle (sizinkiyle değil) döndürdüğünü bulursanız, bu talihsiz bir durumdur ve ben onları normalleştirmek için sarardım.)

Ayrıca bkz. Https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty


1
Bu null, hiçbir öğenin mantıklı bir kongre kullanma meselesi olmadığı anlamına gelmez . Sadece aslında yerli OLESTRINGS, düşünmek yok demek oluyor.
Deduplicator

1
@Deduplicator, Microsoft'un Nesne Bağlama ve Katıştırma şansı hakkında mı konuşuyorsunuz? Hadi hatırlayalım ki ole 90'lı yıllardan! Halen daha fazla bakıldığında, birçok modern dil (C #, Java, Swift), null kullanımını ortadan kaldırmak / ortadan kaldırmak için olanaklar sağlamaktadır.
Erik Eidt

2
@ErikEidt Bunu yapıyorlar, kısmen, çünkü null"eksik bilgi" demek değil. nullTek bir anlamlı yorumu yoktur. Bunun yerine, nasıl davrandığınızla ilgilidir. nullbazen "eksik bilgi", aynı zamanda "eleman yok" ve ayrıca "bir hata oluştu" veya "başlatılmamış" veya "çakışan bilgi" veya bazı keyfi, geçici işlemler için de kullanılır.
Derek Elkins,

-1. Bu, soyut teoriler tarafından değil geliştirici tarafından verilen bir karardır. nullkesinlikle "veri yok" demek için kullanılır. Bazen mantıklı geliyor. Diğer zamanlarda değil.
jpmc26

13

Boş koşullu sözdiziminin yanı sıra, bu sorunu hafifletmek için başka bir teknik daha var: değişkeninizin hiç kalmasına izin vermeyin null.

Bir koleksiyonu parametre olarak kabul eden bir işlev düşünün. İşlevin amaçları için nullboş ve boş ise null, başlangıçta hiçbir zaman içermediğinden emin olabilirsiniz :

public MyResult DoSomething(int a, IEnumerable<string> words)
{
    words = words ?? Enumerable.Empty<string>();

    if (!words.Any())
    {
        ...

Başka bir yöntemden koleksiyon alırken de aynısını yapabilirsiniz:

var words = GetWords() ?? Enumerable.Empty<string>();

( Boş bir koleksiyona benzer bir işlev üzerinde kontrol sahibi olduğunuz GetWordsve nulleşdeğeri olduğu durumlarda, boş koleksiyonun ilk etapta geri döndürülmesi tercih edilir.)

Artık koleksiyonda dilediğiniz herhangi bir işlemi gerçekleştirebilirsiniz. Bu, özellikle toplama sırasında başarısız olacak birçok işlemi gerçekleştirmeniz gerektiğinde nullve boş bir numaralandırılabilir döngü veya sorgulama yaparak aynı sonucu almanız durumunda, ifkoşulların tamamen ortadan kaldırılmasına izin verir .


12

Yanlış mıyım, bu kodun bir müşterisi olarak, örneğin ((int []) null) .Any () öğesinin false döndürmesi beklenirken?

Evet, çünkü C # 'ta olduğunuz için ve bu davranış iyi tanımlanmış ve belgelenmiştir.

Kendi kütüphanenizi yapıyorsanız veya farklı istisna kültürü olan farklı bir dil kullanıyorsanız, yanlış beklemeniz daha mantıklı olacaktır.

Şahsen geri dönüşün yanlış olduğunu sanıyorum, programınızı daha güçlü kılan daha güvenli bir yaklaşım ama en azından tartışmalı.


15
Bu 'sağlamlık' genellikle bir yanılsamadır - diziyi oluşturan kod bir hata veya başka bir sorun nedeniyle beklenmedik bir şekilde NULL'lar oluşturmaya başlarsa, 'sağlam' kodunuz sorunu gizleyecektir. Zaman zaman uygun davranış, ancak güvenli bir varsayılan değil.
GoatInTheMachine 19:18

1
@GoatInTheMachine - Güvenli bir varsayılan olduğu konusunda hemfikir değilim, ancak sorunu gizlemekte haklısınız ve bu tür davranışların zaman zaman istenmeyen olması. Tecrübelerime göre, sorunu gizlemek (veya diğer kodların problemlerini yakalamak için birim testlerine güvenmek) beklenmedik istisnalar atarak uygulamanızı çökertmekten daha iyidir. Gerçekten - çağrı kodu boş olarak gönderilecek kadar bozuksa, istisnaları doğru bir şekilde ele alma şansı nedir?
Telastyn

10
Bir şey bozulursa, benim kodum, başka bir meslektaşım veya bir müşterinin kodu olsun, kodun derhal başarısız olmasını ve insanların belirsiz bir süre için potansiyel olarak tutarsız bir durumda sürdürülmesinden daha çok şey bilmesini tercih ederim. Bunu yapabilmek elbette bazen lüks ve her zaman uygun olmamakla birlikte tercih ettiğim yaklaşım.
GoatInTheMachine 19:18

1
@GoatInTheMachine - Birçok şeye katılıyorum, ancak koleksiyonlar farklı olma eğilimindedir. Boş değerlerin boş bir koleksiyon olarak ele alınması son derece tutarsız veya şaşırtıcı bir davranış değildir.
Telastyn

8
Bir web isteği yoluyla alınan bir JSON belgesinden doldurulmuş bir diziniz olduğunu ve üretim sırasında API'nizin müşterilerinden birinin aniden, kısmen geçersiz JSON aracılığıyla gönderdikleri bir diziyi NULL olarak seri hale getirmenize neden olacak bir sorunu olduğunu düşünün: Kod, en kötüsü, ilk hatalı isteğin geldiği anda NULL referans istisnası oluşturdu; giriş yaparken görürsünüz ve sonra hemen istemciye, kesikli isteklerini düzeltmesini söyleyin, VEYA kodunuz "ah dizilim boş, hiçbir şey yok" diyor. yapmak!" ve sessizce db'ye bir kaç haftalığına 'satın alma sepetinde ürün yoktu' yazdı.
GoatInTheMachine 20:18

10

Tekrarlanan boş değer sizi rahatsız ediyorsa, String yöntemini bu ada göre yansıtmak için kendi 'IsNullOrEmpty ()' uzantı yönteminizi oluşturabilir ve null-check ve .Any () çağrısını tek bir çağrıya sarabilirsiniz.

Aksi taktirde, sorunuzun yorumunda 26'dan 17'sinde belirtilen çözüm, 'standart' yöntemden daha kısadır ve yeni boş koşullu sözdizimini bilen herhangi biri için oldukça açıktır.

if(myCollection?.Any() == true)

4
Bunun ?? falseyerine de kullanabilirsiniz == true. Bu, sadece durumu ele aldığı için bana daha açık (temiz) görünecek nullve gerçekten daha ayrıntılı değil. Artı ==Boolean'lere yönelik çekler genellikle tıkaç refleksimi tetikler. =)
jpmc26

2
@ jpmc26: C # hakkında fazla bir şey bilmiyorum. Neden myCollection?.Any()yeterli değil
Eric Duminil

6
@EricDuminil Boş-koşullu işlecin çalışma şekli nedeniyle, myCollection?.Any()normal bir Boolean yerine (yani, bool yerine bool) etkin bir boş Boole döndürür. Bool'dan örtük dönüşüm yok mu? bool, ve bu özel örnekte ihtiyacımız olan bir bool ( ifkoşulun bir parçası olarak test etmek için ). Bu nedenle, truenull-birleştirici operatör (??) ile açıkça karşılaştırmalı ya da onu kullanmalıyız.
Steven Rands

@ jpmc26 ?? false okumak zor, sonra myCollection? .Any () == true. Tıkaç refleksinizden bağımsız olarak, == true örtüken test etmeye çalıştığınız şeydir. ?? false sadece ek sesler ekler ve kafanızda null olursa neyin olduğu hakkında değerlendirme yapmanız gerekir, çünkü null == true, okuyucunun bile farkında olmadan, neredeyse hiç başarısız olmaz ?..
Ryan Leach

2
@RyanTheLeach ==Gerçekten çalışıp çalışmayacağı konusunda çok daha fazla düşünmek zorundayım . Zaten sadece olmak varken sezgisel bir Boole verilerle ne trueya false; Bunu düşünmek bile zorunda değilim. Ama nullkarışıma atın ve şimdi ==bunun doğru olup olmadığını araştırmalıyım . ??bunun yerine nulldavayı ortadan kaldırır, geri alır trueve onu falsehemen anlarsınız. Tıkaçma refleksime gelince, ilk gördüğümde, derhal içgüdüm, onu genellikle istememek istemeyen işe yaramaz olduğu için silmek.
jpmc26

8

Yanlış mıyım, bu kodun bir müşterisi olarak, örneğin ((int []) null) .Any () öğesinin false döndürmesi beklenirken?

Beklentileri merak ediyorsanız niyetleri düşünmeniz gerekir.

null çok farklı bir şey anlamına gelir Enumerable.Empty<T>

Erik Eidt'in cevabında da belirtildiği gibi , nullboş bir koleksiyon ile anlam arasında bir fark vardır .

İlk önce nasıl kullanılmaları gerektiği üzerine bir göz atalım.

Kitap Çerçeve Tasarım Kuralları: Yeniden kullanılabilir NET Kütüphaneleri ilişkin anlaşmalar, Deyimler ve Desenler, 2nd Edition , Microsoft mimarlar tarafından yazılan Krzysztof Cwalina ve Brad Abrams aşağıdaki en iyi uygulamayı bildiren:

X null değerleri toplama özelliklerinden veya koleksiyonları döndüren yöntemlerden döndürmeyin. Bunun yerine boş bir koleksiyon veya boş bir dizi döndür.

Sonunda bir veritabanından veri alan bir yöntemi çağırdığınızı düşünün: Boş bir dizi alırsanız veya Enumerable.Empty<T>bu basitçe örnek alanınızın boş olduğu anlamına gelir , yani sonuç boş bir kümedir . Alma nullbu bağlamda, ancak, bir delalet edecek hata durumunu .

Dan Wilson'un patates analojisiyle aynı düşünce biçiminde , boş bir set olsa bile verileriniz hakkında sorular sormak mantıklıdır . Ancak , set yoksa, çok daha az mantıklı .


1
Farklı anlamlara sahip olup olmadıkları, içeriğe oldukça bağlıdır. Çoğunlukla, elindeki mantık ne olursa olsun, eşdeğer kavramları temsil ederler. Her zaman değil , ama sık sık.
jpmc26 20:18

1
@ jpmc26: Bence bu cevabın amacı c # 'nın kodlama kurallarına göre farklı bir anlama sahip olduklarını söylemek olduğunu düşünüyorum. İsterseniz, boş ve boş olan her zaman aynı kodu kullanabilirsiniz. Bazı durumlarda, boş veya boş olsa da aynı şeyi yapabilirsiniz, ancak bu aynı anlama geldikleri anlamına gelmez.
Chris

@Chris Ve dili tasarlayan insanlardan gelen kodlama kurallarının, kodunuzu gereksinimleriniz, kullandığınız kütüphaneler ve birlikte çalıştığınız diğer geliştiriciler bağlamında değerlendirmek için kullanılamaz. Asla bağlamda eşdeğer olmayacakları fikri, gökyüzündeki turta idealizmidir. Genel olarak eldeki verilerle eşdeğer olmayabilirler, ancak yazdığınız belirli bir işlevde sonuç oluşturmak için eşdeğer olabilirler; Bu durumda, ikisini de desteklemeniz gerekir , ancak aynı sonucu aldıklarından emin olun.
jpmc26 21:18

Söylediklerinizle kafam karışabilir ama boş ve boş bir sonuç üretmek için eşdeğer olduğunda, neden sadece ayrı kullanmayacağınızı anlamıyorum, aynı anda hem de aynı anda yapılan bir yöntemi istemek yerine boş kontroller. diğer durumlarda onları ayırt etmenize izin vermiyor ...
Chris

@Chris Farklı bağlamlara (genellikle kapsamlara karşılık gelir) sahip olmaktan bahsediyorum. Örneğin bir işlev düşünün. nullve empty, işlev için aynı dönüş değerine neden olabilir, ancak bu demek değildir nullve boş, arama kapsamındakiyle tamamen aynı anlama gelir.
jpmc26

3

Neden nullve boşun farklı olduğunu açıklayan birçok cevap var ve neden farklı muamele görmeleri gerekip gerekmediğini açıklamaya çalışan yeterli fikir var . Ancak soruyorsun:

Yanlış mıyım, bu kodun bir müşterisi olarak, örneğin ((int []) null) .Any () öğesinin false döndürmesi beklenirken?

Mükemmel bir beklenti . Şu anki davranışı savunan biri kadar haklısın . Mevcut uygulama felsefesine katılıyorum, ancak itici faktörler bağlam dışı düşüncelere dayanarak - sadece - değil.

Tahmini Any()olmadan temelde Count() > 0verilen bu parçacığı ne bekliyorsunuz?

List<int> list = null;
if (list.Count > 0) {}

Veya genel:

List<int> list = null;
if (list.Foo()) {}

Umarım beklersiniz NullReferenceException.

  • Any()bir uzatma yöntemidir, uzatılmış nesneyle sorunsuz bir şekilde bütünleşmelidir, ardından bir istisna atmak en şaşırtıcı şeydir.
  • Her .NET dili uzantı yöntemlerini desteklemez.
  • Her zaman arayabilir Enumerable.Any(null)ve orada kesinlikle beklediğiniz ArgumentNullException. Bu aynı yöntemdir ve Çerçeve'de neredeyse her şeyle (muhtemelen) neredeyse tutarlı olmak zorundadır.
  • Bir nullnesneye erişim bir programlama hatasıdır , çerçeve null değeri kadar boş bırakmamalıdır . Bu şekilde kullanırsanız, onunla başa çıkmak sizin sorumluluğunuzdadır.
  • Bu oluyor opinionated tek yolu olduğunu düşünüyorum ve başka bir yol düşünmek. Çerçeve mümkün olduğunca açıklanmamış olmalıdır.
  • Özel bir durumunuz varsa, tutarlı olmalısınız : diğer bütün uzatma yöntemleri hakkında daha fazla ve çok daha fazla karar almak zorundasınız: Count()kolay bir karar gibi görünüyorsa Where(), öyle değil. Ne hakkında Max()? Bir EMPTY listesi için bir istisna atar, bir tane için de atmaz nullmı?

Kütüphane tasarımcılarının LINQ'dan önce yaptığı nullşey, geçerli bir değer olduğunda (örneğin String.IsNullOrEmpty()) geçerli yöntemler ortaya koymaktı, daha sonra mevcut tasarım felsefesi ile tutarlı olmaları HAD idi . Bu, yazmak için oldukça önemsiz olsa bile, iki yöntem EmptyIfNull()ve EmptyOrNull()kullanışlı olabilir.


1

Jim'in her çantada patates bırakması gerekiyordu. Yoksa onu öldürürüm.

Jim'in içinde beş tane patates bulunan bir çanta var. .Any()Çantada patates var mı?

"Evet" diyorsun. <= doğru

Tamam, Jim bu sefer yaşıyor.

Jim bütün patatesleri çıkarır ve onları yer. Çantada herhangi bir () patates var mı?

"Hayır" diyorsun. <= yanlış

Jim'i öldürme zamanı.

Jim, çantayı tamamen ateşe yakar. Şu anda çantada herhangi bir () patates var mı?

"Çanta yok." <= ArgumentNullException

Jim yaşamalı mı yoksa ölmeli mi? Bunu beklemiyorduk bu yüzden bir karar vermem gerekiyor. Jim'in bununla bir hata yapmasına izin vermek mi değil mi?

Sen edebilirsiniz ek açıklamalar kullanabilirsiniz herhangi boş maskaralık ile bu şekilde koyarak değiliz sinyal.

public bool Any( [NotNull] List bag ) 

Fakat takım zinciriniz bunu desteklemeli. Bu da muhtemelen çek yazmaya devam edeceğiniz anlamına geliyor.


0

Bu sizi çok rahatsız ediyorsa, basit bir uzatma yöntemi öneririm.

static public IEnumerable<T> NullToEmpty<T>(this IEnumerable<T> source)
{
    return (source == null) ? Enumerable.Empty<T>() : source;
}

Şimdi bunu yapabilirsiniz:

List<string> list = null;
var flag = list.NullToEmpty().Any( s => s == "Foo" );

... ve bayrak olarak ayarlanacak false.


2
returnreturn source ?? Enumerable.Empty<T>();
İfadesini

Bu sorulan soruyu cevaplamıyor.
Kenneth K.

@ KennethK.but sunulan sorunu çözmek gibi görünüyor.
RQDQ

0

Bu, C # 'nın uzatma yöntemleri ve tasarım felsefeleri ile ilgili bir soru, bu yüzden bu soruyu cevaplamanın en iyi yolunun MSDN’nin dokümantasyonunu uzatma yöntemleri amacıyla sunmak olduğunu düşünüyorum :

Uzantı yöntemleri, yeni türetilmiş bir tür oluşturmadan, yeniden derlemeden veya orijinal türünü değiştirmeden mevcut türlere yöntemleri "eklemenizi" sağlar. Genişletme yöntemleri özel bir statik yöntemdir, ancak genişletilmiş türdeki örnek yöntemleri olarak adlandırılırlar. C #, F # ve Visual Basic ile yazılmış istemci kodu için, bir uzatma yöntemini çağırmakla ve aslında bir türde tanımlanmış yöntemler arasında belirgin bir fark yoktur.

...

Genel olarak, uzatma yöntemlerini az miktarda ve sadece gerektiğinde uygulamanızı öneririz. Mümkün olduğunda, mevcut bir türü genişletmesi gereken müşteri kodunun, mevcut türden türetilmiş yeni bir tür oluşturarak yapması gerekir. Daha fazla bilgi için, bkz. Miras.

Kaynak kodunu değiştiremeyeceğiniz bir türü genişletmek için bir uzantı yöntemi kullanırken, türün uygulanmasındaki bir değişikliğin uzantı yönteminizin bozulmasına neden olma riski vardır.

Belirli bir tür için uzatma yöntemleri uygularsanız, aşağıdaki noktaları unutmayın:

  • Bir uzatma yöntemi, türünde tanımlanan bir yöntemle aynı imzaya sahipse asla çağrılmaz.
  • Genişletme yöntemleri, isim alanı seviyesinde kapsam içine alınmıştır. Örneğin, adlandırılmış tek bir ad alanında uzantı yöntemleri içeren birden fazla statik sınıfınız varsa Extensions, tümü using Extensions;yönergeyle kapsam içine alınacaktır .

Özetlemek gerekirse, genişletme yöntemleri, geliştiriciler bunu doğrudan yapamadığında bile, belirli bir türe örnek yöntemleri eklemek için tasarlanmıştır. Örnek yöntemler olacaktır çünkü her zaman uzatma yöntemleri geçersiz (örnek yöntemi sözdizimini kullanarak denir ise) mevcut, bu gerekip gerekmediğini sadece doğrudan bir yöntem eklemek veya sınıfını uzatamaz eğer yapılması. *

Başka bir deyişle, bir uzatma yöntemi tıpkı bir örnek yöntemi gibi davranmalıdır, çünkü bazı müşteriler tarafından bir örnek yöntemi oluşturulabilir. Ayrıca, çağrıldığı nesne olduğu takdirde bir örnek yöntemi de atmalıdır null, uzantı yöntemi de öyle olmalıdır.


C # 3.0 kullanıma sunulduğunda, orada kullandığınız müşterilerine milyonlarca zaten: * Bir yan not olarak, bu LINQ tasarımcıları karşı karşıya olduğunu tam olarak durumdur System.Collections.IEnumerableve System.Collections.Generic.IEnumerable<T>onların koleksiyonlarında ve hem de foreachdöngüler. Bu sınıflar, geri IEnumerator, sadece iki yöntem olan nesneler Currentve MoveNextçok gibi herhangi bir ek gerekli örnek yöntemleri, ekleme, Count, Anyvb müşterilerin bu milyonlarca kırılma olacaktır. Dolayısıyla, bu işlevselliği sağlamak için (özellikle nispeten kolay Currentve MoveNextgöreceli olarak uygulanabildiği için), mevcut durumda olan herhangi birisine uygulanabilecek olan uzatma yöntemleri olarak yayınladılar.IEnumerableörneği ve ayrıca sınıflar tarafından daha verimli bir şekilde uygulanabilir. C # 'nin tasarımcıları ilk gün LINQ’yu piyasaya sürmeye karar vermiş olsalardı, örnek metotlar olarak sağlanmışlardı IEnumerableve muhtemelen bu metotların varsayılan arayüz uygulamalarını sağlamak için bir tür sistem tasarlamışlardı.


0

Bence burada dikkat çeken nokta, bir istisna atmak yerine false döndürerek, kodunuzun gelecekteki okuyucuları / değiştiricileriyle ilgili olabilecek bilgileri gizlemiş olmanızdır.

Listenin boş olması mümkünse, bunun için ayrı bir mantık yoluna sahip olmanızı öneririm, aksi halde ileride birileri sizin if'nizin diğerine {} göre bazı liste tabanlı bir mantık ekleyebilir. Tahmin etmek için hiçbir nedenleri olmadığı için istenmeyen bir istisna.

Okunabilirlik ve bakım kolaylığı, her seferinde “fazladan bir durum yazmalıyım” dır.


0

Genel bir kural olarak, kodun çoğunu, arayanın null veriyi vermemekten sorumlu olduğunu varsaymak için yazarım, çoğunlukla Null Say'a (ve benzeri diğer mesajlarda) belirtilen sebeplerden dolayı, beni boş veri dağıtmaktan sorumludur . Boş (null) kavramı genellikle iyi anlaşılmamıştır ve bu nedenle değişkenlerinizi zamanından önce mümkün olduğu kadar başlatmanız önerilir. Makul bir API ile çalıştığınızı varsayarak, ideal olarak hiçbir zaman bir boş değer elde etmemelisiniz, bu nedenle hiçbir zaman boşluğu kontrol etmemelisiniz. Diğer cevapların da belirttiği gibi, boş olan nokta, devam etmeden önce üzerinde çalışacağınız geçerli bir nesnenin (örneğin bir "çanta") olduğundan emin olmaktır. Bu bir özellik değil Any, dilin bir özelliğidir.kendisi. Boş bir nesnede çoğu işlemi yapamazsınız, çünkü mevcut değil. Bir arabam yokken, arabamdaki mağazaya gitmenizi rica ediyorum, böylece arabamı markete sürmek için kullanamazsınız. Kelimenin tam anlamıyla var olmayan bir şey üzerinde işlem yapmak saçma.

Kelimenin tam anlamıyla istenen bilgileri almadığınızda (örneğin, size yaşımın ne olduğunu sorduysam, bu noktada cevap vermeniz en olası seçenek "bilmiyorum" gibi boş kullanım için pratik durumlar vardır. ", boş olan değer budur). Bununla birlikte, çoğu durumda, en azından değişkenlerinizin başlatılıp başlatılmadığını bilmeniz gerekir. Ve eğer yapmazsan, o zaman kodunu sıkman gerektiğini tavsiye ederim. Herhangi bir programda veya fonksiyonda yaptığım ilk şey, kullanmadan önce bir değeri başlatmak. Null değerlerini kontrol etmem gerekiyor, çünkü değişkenlerimin null olmadığını garanti edebilirim. Girmek iyi bir alışkanlıktır ve değişkenlerinizi başlatmayı ne kadar sık ​​hatırlarsanız, null değerini kontrol etmeniz de o kadar az olur.

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.