Bu genel bir soru (ama C # kullanıyorum), en iyi yol nedir (en iyi uygulama), dönüş türü olarak bir koleksiyonu olan bir yöntem için boş veya boş toplama döndürüyor musunuz?
Bu genel bir soru (ama C # kullanıyorum), en iyi yol nedir (en iyi uygulama), dönüş türü olarak bir koleksiyonu olan bir yöntem için boş veya boş toplama döndürüyor musunuz?
Yanıtlar:
Boş toplama. Her zaman.
Bu berbat:
if(myInstance.CollectionProperty != null)
{
foreach(var item in myInstance.CollectionProperty)
/* arrgh */
}
null
Bir koleksiyonu iade ederken veya numaralandırılırken ASLA geri dönmek için en iyi uygulama olarak kabul edilir . DAİMA boş bir numaralandırılabilir / koleksiyon döndürür. Söz konusu saçmalığı önler ve aracınızın meslektaşlarınız ve sınıflarınızın kullanıcıları tarafından engellenmesini önler.
Mülkler hakkında konuşurken, mülkünüzü her zaman bir kez ayarlayın ve unutun
public List<Foo> Foos {public get; private set;}
public Bar() { Foos = new List<Foo>(); }
.NET 4.6.1'de bunu oldukça yoğunlaştırabilirsiniz:
public List<Foo> Foos { get; } = new List<Foo>();
Numaralandırılabilir döndüren yöntemler hakkında konuşurken, yerine boş bir numaralandırılabilir kolayca dönebilirsiniz null
...
public IEnumerable<Foo> GetMyFoos()
{
return InnerGetFoos() ?? Enumerable.Empty<Foo>();
}
Kullanmak Enumerable.Empty<T>()
, örneğin yeni bir boş koleksiyon veya dizi döndürmekten daha verimli olarak görülebilir.
IEnumerable
veya ICollection
o kadar önemli değildir. Her neyse, tür bir şey seçerseniz ICollection
onlar da geri dönüyorlar null
... Boş bir koleksiyon geri dönmelerini isterdim, ama geri dönenlere koştum null
, bu yüzden burada bahsettiğimi düşündüm. Numaralandırılabilir bir koleksiyonun varsayılan değerinin boş olmadığını söyleyebilirim. Çok hassas bir konu olduğunu bilmiyordum.
Gönderen Çerçeve Tasarım Kuralları 2. Baskı (pg 256.):
Koleksiyon özelliklerinden veya koleksiyon döndüren yöntemlerden boş değerler döndürmeyin. Bunun yerine boş bir koleksiyon veya boş bir dizi döndürün.
Burada null'ları döndürmemenin yararları hakkında ilginç bir makale daha var (Brad Abram'ın blogunda bir şeyler bulmaya çalışıyordum ve makaleye bağlandı).
Düzenleme - Eric Lippert'in orijinal soruya yorum yaptığı gibi , mükemmel makalesine de bağlantı vermek istiyorum .
Senin bağlıdır sözleşme ve somut durumda . Genellikle boş koleksiyonları iade etmek en iyisidir , ancak bazen ( nadiren ):
null
daha spesifik bir şey anlamına gelebilir;null
.Bazı somut örnekler:
null
öğenin eksik olduğu anlamına gelirken, boş bir koleksiyon gereksiz (ve muhtemelen yanlış)<collection />
Henüz bahsedilmeyen başka bir nokta daha var. Aşağıdaki kodu göz önünde bulundurun:
public static IEnumerable<string> GetFavoriteEmoSongs()
{
yield break;
}
Bu yöntemi çağırırken C # Dili boş bir numaralandırıcı döndürür. Bu nedenle, dil tasarımına (ve dolayısıyla programcı beklentilerine) uymak için boş bir koleksiyon iade edilmelidir.
Boş daha tüketici dostu.
Boş bir numaralandırılabilir yapmak için açık bir yöntem vardır:
Enumerable.Empty<Element>()
Bana öyle geliyor ki, bağlamsal olarak anlamsal olarak doğru olan değeri, ne olursa olsun döndürmelisiniz. "Her zaman boş bir koleksiyon iade edin" yazan bir kural benim için biraz basit görünüyor.
Diyelim ki, bir hastane sistemi için, son 5 yıl için önceki tüm hastaneye yatışların bir listesini döndürmesi gereken bir fonksiyonumuz var. Müşteri hastaneye gitmediyse boş bir listeye geri dönmek mantıklıdır. Peki ya müşteri başvuru formunun bu kısmını boş bırakırsa? "Boş liste" yi "yanıt yok" veya "bilmiyorum" ifadesinden ayırmak için farklı bir değere ihtiyacımız var. Bir istisna atabiliriz, ancak bu mutlaka bir hata koşulu değildir ve bizi normal program akışından çıkarmayabilir.
Sık sık sıfır ile cevap veremeyen sistemleri ayırt edemiyorum. Bir sistemin bir sayı girmemi istediği birkaç kez yaşadım, sıfır giriyorum ve bu alana bir değer girmem gerektiğini söyleyen bir hata mesajı alıyorum. Az önce yaptım: Sıfır girdim! Ama sıfırı kabul etmez, çünkü cevabı hiçbirinden ayırt edemez.
Saunders Cevapla:
Evet, "Kişi soruya cevap vermedi" ile "Cevap sıfırdı" arasında bir fark olduğunu varsayıyorum. Cevabımın son paragrafının noktası buydu. Birçok program "bilmiyorum" u boş veya sıfırdan ayıramaz, bu da bana potansiyel olarak ciddi bir kusur gibi görünüyor. Örneğin, bir yıl kadar önce bir ev için alışveriş yapıyordum. Bir emlak web sitesine gittim ve 0 $ 'lık bir fiyatla listelenen birçok ev vardı. Bana çok iyi geldi: Bu evleri bedava veriyorlar! Ama eminim ki üzücü gerçek şu ki fiyatına girmemiş olmalarıydı. Bu durumda, "EĞER, ZORUNLU sıfır, fiyata girmedikleri anlamına gelir - hiç kimse ücretsiz bir ev veremez." Ancak site aynı zamanda çeşitli kasabalardaki evlerin ortalama soran ve satış fiyatlarını da listeledi. Yardım edemem ama ortalama sıfırlar dahil olmadığını merak ediyorum, böylece bazı yerler için yanlış düşük bir ortalama vererek. yani ortalama 100.000 dolar nedir; 120.000 $; ve "bilmiyorum"? Teknik olarak cevap "bilmiyorum". Muhtemelen gerçekten görmek istediğimiz şey 110.000 dolar. Ama muhtemelen alacağımız 73.333 $, ki bu tamamen yanlış olurdu. Ayrıca, kullanıcıların çevrimiçi olarak sipariş verebilecekleri bir sitede bu sorunu yaşarsak ne olur? (Emlak için olası değil, ama eminim diğer birçok ürün için yapıldığını gördüm.) Gerçekten "henüz belirtilmemiş fiyat" "ücretsiz" olarak yorumlanmasını ister misiniz? böylece bazı yerler için yanlış düşük bir ortalama verir. yani ortalama 100.000 dolar nedir; 120.000 $; ve "bilmiyorum"? Teknik olarak cevap "bilmiyorum". Muhtemelen gerçekten görmek istediğimiz şey 110.000 dolar. Ama muhtemelen alacağımız 73.333 $, ki bu tamamen yanlış olurdu. Ayrıca, kullanıcıların çevrimiçi olarak sipariş verebilecekleri bir sitede bu sorunu yaşarsak ne olur? (Emlak için olası değil, ama eminim diğer birçok ürün için yapıldığını gördüm.) Gerçekten "henüz belirtilmemiş fiyat" "ücretsiz" olarak yorumlanmasını ister misiniz? böylece bazı yerler için yanlış düşük bir ortalama verir. yani ortalama 100.000 dolar nedir; 120.000 $; ve "bilmiyorum"? Teknik olarak cevap "bilmiyorum". Muhtemelen gerçekten görmek istediğimiz şey 110.000 dolar. Ama muhtemelen alacağımız 73.333 $, ki bu tamamen yanlış olurdu. Ayrıca, kullanıcıların çevrimiçi olarak sipariş verebilecekleri bir sitede bu sorunu yaşarsak ne olur? (Emlak için olası değil, ama eminim diğer birçok ürün için yapıldığını gördüm.) Gerçekten "henüz belirtilmemiş fiyat" "ücretsiz" olarak yorumlanmasını ister misiniz? ki bu tamamen yanlış olur. Ayrıca, kullanıcıların çevrimiçi olarak sipariş verebilecekleri bir sitede bu sorunu yaşarsak ne olur? (Emlak için olası değil, ama eminim diğer birçok ürün için yapıldığını gördüm.) Gerçekten "henüz belirtilmemiş fiyat" "ücretsiz" olarak yorumlanmasını ister misiniz? ki bu tamamen yanlış olur. Ayrıca, kullanıcıların çevrimiçi olarak sipariş verebilecekleri bir sitede bu sorunu yaşarsak ne olur? (Emlak için olası değil, ama eminim diğer birçok ürün için yapıldığını gördüm.) Gerçekten "henüz belirtilmemiş fiyat" "ücretsiz" olarak yorumlanmasını ister misiniz?
RE'nin iki ayrı işlevi vardır, bir "var mı?" ve "eğer öyleyse, nedir?" Evet, kesinlikle yapabilirsin, ama neden yapmak istersin? Şimdi çağrı programı bir yerine iki çağrı yapmak zorunda. Bir programcı "herhangi biri" olarak adlandırmazsa ne olur? ve doğrudan "bu nedir?" ? Program yanlış yönlendiren bir sıfır döndürür mü? İstisna atmak mı? Tanımlanmamış bir değer döndürülsün mü? Daha fazla kod, daha fazla çalışma ve daha fazla potansiyel hata oluşturur.
Gördüğüm tek fayda, keyfi bir kurala uymanızı sağlaması. Bu kurala uyma zahmetine değecek bir avantaj var mı? Değilse, neden rahatsız oluyorsun?
Jammycakes için yanıt:
Gerçek kodun nasıl görüneceğini düşünün. Sorunun C # dediğini biliyorum ama Java yazdığımda izin verin. C #'m çok keskin değil ve prensip aynı.
Boş bir dönüşle:
HospList list=patient.getHospitalizationList(patientId);
if (list==null)
{
// ... handle missing list ...
}
else
{
for (HospEntry entry : list)
// ... do whatever ...
}
Ayrı bir işlevle:
if (patient.hasHospitalizationList(patientId))
{
// ... handle missing list ...
}
else
{
HospList=patient.getHospitalizationList(patientId))
for (HospEntry entry : list)
// ... do whatever ...
}
Aslında null dönüşü olan bir satır veya iki daha az kod, bu yüzden arayan için daha fazla yük değil, daha az.
Nasıl KURU bir sorun oluşturduğunu görmüyorum. Çağrıyı iki kez yapmak zorunda değiliz. Liste olmadığında her zaman aynı şeyi yapmak isteseydik, belki de arayanın bunu yapmaktan ziyade get-list işlevine devam etmeyi zorlayabiliriz ve bu nedenle kodu arayana koymak KURU ihlali olur. Ama neredeyse her zaman aynı şeyi yapmak istemiyoruz. İşlenecek listeye sahip olmamız gereken işlevlerde, eksik bir liste işlenmeyi durdurabilecek bir hatadır. Ancak bir düzenleme ekranında, henüz veri girmemişlerse işlemeyi durdurmak istemiyoruz: veri girmelerine izin vermek istiyoruz. Bu nedenle "liste yok" işleminin arayan düzeyinde şu veya bu şekilde yapılması gerekir. Ve bunu boş bir dönüşle mi yoksa ayrı bir işlevle mi yapacağız, daha büyük prensipte hiçbir fark yaratmaz.
Elbette, arayan null olup olmadığını kontrol etmezse, program null-pointer istisnası ile başarısız olabilir. Ancak ayrı bir "var" işlevi varsa ve arayan kişi bu işlevi çağırmaz, ancak körü körüne "listeyi al" işlevini çağırırsa ne olur? Bir istisna atarsa veya başka bir şekilde başarısız olursa, bu, null döndürdüğünde ve kontrol etmediyse ne olacağıyla hemen hemen aynıdır. Boş bir liste döndürürse, bu sadece yanlış. "Sıfır öğeli bir listem var" ile "listem yok" arasında ayrım yapmıyorsunuz. Kullanıcı herhangi bir fiyat girmediğinde fiyat için sıfır döndürmek gibi: sadece yanlış.
Koleksiyona ek bir özellik eklemenin nasıl yardımcı olduğunu görmüyorum. Arayan hala kontrol etmelidir. Boş değeri kontrol etmekten daha iyi ne olabilir? Yine, olabilecek en kötü şey, programcının kontrol etmeyi unutması ve yanlış sonuçlar vermesidir.
Null döndüren bir işlev, programcı null anlamı "değeri yok" kavramına aşina ise sürpriz değildir, ki herhangi bir yetkili programcının iyi bir fikir olup olmadığını düşünüp düşünmediğini düşünmesi gerektiğini düşünüyorum. Ayrı bir işleve sahip olmanın daha çok "sürpriz" bir sorun olduğunu düşünüyorum. Bir programcı API'yı bilmiyorsa, veri içermeyen bir test çalıştırdığında, bazen boş bir değer aldığını hızlı bir şekilde keşfeder. Fakat böyle bir fonksiyon olabileceği ve dokümantasyonu kontrol ettiği ve dokümantasyonun tam ve anlaşılabilir olmadığı sürece başka bir fonksiyonun varlığını nasıl keşfeder? Her ikisini de aramam gerektiğini bilmem ve hatırlamam gereken iki işlev yerine, bana her zaman anlamlı bir yanıt veren bir işlevim olmasını tercih ederim.
Boş bir koleksiyon semantik olarak anlamlıysa, geri dönmeyi tercih ederim. GetMessagesInMyInbox()
İletişim için boş bir koleksiyon döndürmek, "gerçekten gelen kutunuzda hiç mesajınız yok" iletmekle birlikte, geri dönüş, geri null
döndürülebilecek listenin neye benzemesi gerektiğini söylemek için yeterli veri olmadığını bildirmek için yararlı olabilir.
null
değer kesinlikle makul görünmüyor, ben bu konuda daha genel anlamda düşünüyordum. İstisnalar da bir şeyin yanlış gittiğini bildirmek için harikadır, ancak atıfta bulunulan "yetersiz veri" mükemmel bir şekilde bekleniyorsa, bir istisna atmak kötü tasarım olacaktır. Oldukça mükemmel bir şekilde mümkün olduğu ve bazen bir yanıt hesaplamak mümkün değildir yöntemi için hiçbir hata nerede bir senaryo düşünüyorum.
Yeni bir nesne oluşturulmadığından, null değerini döndürmek daha verimli olabilir. Bununla birlikte, genellikle bir null
kontrol (veya istisna işleme) de gerektirir .
Anlamsal olarak null
boş bir liste aynı anlama gelmez. Farklılıklar belirsizdir ve belirli durumlarda bir seçenek diğerinden daha iyi olabilir.
Seçiminiz ne olursa olsun, karışıklığı önlemek için belgeyi belgeleyin.
Duruma göre. Bu özel bir durumsa, null değerini döndürün. Eğer fonksiyon sadece boş bir koleksiyon döndürürse, o zaman tabii ki geri dönüyor. Ancak, boş parametrelerin geçersiz parametreler veya diğer nedenlerden dolayı özel bir durum olarak döndürülmesi iyi bir fikir DEĞİLDİR, çünkü özel durum durumunu maskelemektedir.
Aslında, bu durumda GERÇEKTEN göz ardı edilmediğinden emin olmak için genellikle bir istisna atmayı tercih ederim :)
Kodun daha sağlam hale getirildiğini söylemek (boş bir koleksiyon döndürerek), boş koşulu işlemek zorunda olmadıkları için kötüdür, çünkü sadece çağrı kodu tarafından ele alınması gereken bir sorunu maskelemektedir.
Bunun null
boş bir koleksiyonla aynı şey olmadığını ve hangisinin geri döndüğünüzü en iyi temsil ettiğini seçmelisiniz. Çoğu durumda null
(SQL hariç) hiçbir şey yoktur. Boş bir koleksiyon, boş bir şey de olsa bir şeydir.
Birini ya da diğerini seçmek zorunda kalırsanız, null yerine boş bir koleksiyona yönelmeniz gerektiğini söyleyebilirim. Ancak boş bir koleksiyonun null değerle aynı olmadığı zamanlar vardır.
Her zaman müşterilerinizi (API'nızı kullanan) lehine düşünün:
'Null' değerinin çok sık döndürülmesi, istemcilerin null denetimleri doğru işlememesi ile ilgili sorunlara neden olur ve bu da çalışma zamanı sırasında NullPointerException özelliğine neden olur. Böyle bir eksik null-kontrolün bir öncelikli üretim sorununu zorladığı durumlar gördüm (müşteri null değerinde foreach (...) kullandı). Test sırasında sorun oluşmadı, çünkü üzerinde çalışan veriler biraz farklıydı.
Burada uygun bir örnekle açıklama yapmayı seviyorum.
Burada bir dava düşünün ..
int totalValue = MySession.ListCustomerAccounts()
.FindAll(ac => ac.AccountHead.AccountHeadID
== accountHead.AccountHeadID)
.Sum(account => account.AccountValue);
İşte kullandığım fonksiyonları düşünün ..
1. ListCustomerAccounts() // User Defined
2. FindAll() // Pre-defined Library Function
Kolayca kullanabilir ListCustomerAccount
ve FindAll
yerine.,
int totalValue = 0;
List<CustomerAccounts> custAccounts = ListCustomerAccounts();
if(custAccounts !=null ){
List<CustomerAccounts> custAccountsFiltered =
custAccounts.FindAll(ac => ac.AccountHead.AccountHeadID
== accountHead.AccountHeadID );
if(custAccountsFiltered != null)
totalValue = custAccountsFiltered.Sum(account =>
account.AccountValue).ToString();
}
Not: AccountValue olmadığından null
, Sum () işlevi döndürmez null
. Bu nedenle doğrudan kullanabilirsiniz.
Boş bir koleksiyonu iade etmek çoğu durumda daha iyidir.
Bunun nedeni, arayanın uygulanmasının kolaylığı, tutarlı sözleşme ve daha kolay uygulamadır.
Bir yöntem boş sonucu belirtmek için null değerini döndürürse, arayan numaralandırmaya ek olarak bir null kontrol adaptörü de uygulamalıdır. Bu kod daha sonra çeşitli arayanlarda çoğaltılır, bu yüzden bu bağdaştırıcıyı yeniden kullanılabilir olması için yöntemin içine koymuyoruz.
IEnumerable için null değerinin geçerli bir kullanımı, eksik bir sonucun veya bir işlem arızasının göstergesi olabilir, ancak bu durumda istisna atma gibi diğer teknikler göz önünde bulundurulmalıdır.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace StackOverflow.EmptyCollectionUsageTests.Tests
{
/// <summary>
/// Demonstrates different approaches for empty collection results.
/// </summary>
class Container
{
/// <summary>
/// Elements list.
/// Not initialized to an empty collection here for the purpose of demonstration of usage along with <see cref="Populate"/> method.
/// </summary>
private List<Element> elements;
/// <summary>
/// Gets elements if any
/// </summary>
/// <returns>Returns elements or empty collection.</returns>
public IEnumerable<Element> GetElements()
{
return elements ?? Enumerable.Empty<Element>();
}
/// <summary>
/// Initializes the container with some results, if any.
/// </summary>
public void Populate()
{
elements = new List<Element>();
}
/// <summary>
/// Gets elements. Throws <see cref="InvalidOperationException"/> if not populated.
/// </summary>
/// <returns>Returns <see cref="IEnumerable{T}"/> of <see cref="Element"/>.</returns>
public IEnumerable<Element> GetElementsStrict()
{
if (elements == null)
{
throw new InvalidOperationException("You must call Populate before calling this method.");
}
return elements;
}
/// <summary>
/// Gets elements, empty collection or nothing.
/// </summary>
/// <returns>Returns <see cref="IEnumerable{T}"/> of <see cref="Element"/>, with zero or more elements, or null in some cases.</returns>
public IEnumerable<Element> GetElementsInconvenientCareless()
{
return elements;
}
/// <summary>
/// Gets elements or nothing.
/// </summary>
/// <returns>Returns <see cref="IEnumerable{T}"/> of <see cref="Element"/>, with elements, or null in case of empty collection.</returns>
/// <remarks>We are lucky that elements is a List, otherwise enumeration would be needed.</remarks>
public IEnumerable<Element> GetElementsInconvenientCarefull()
{
if (elements == null || elements.Count == 0)
{
return null;
}
return elements;
}
}
class Element
{
}
/// <summary>
/// http://stackoverflow.com/questions/1969993/is-it-better-to-return-null-or-empty-collection/
/// </summary>
class EmptyCollectionTests
{
private Container container;
[SetUp]
public void SetUp()
{
container = new Container();
}
/// <summary>
/// Forgiving contract - caller does not have to implement null check in addition to enumeration.
/// </summary>
[Test]
public void UseGetElements()
{
Assert.AreEqual(0, container.GetElements().Count());
}
/// <summary>
/// Forget to <see cref="Container.Populate"/> and use strict method.
/// </summary>
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void WrongUseOfStrictContract()
{
container.GetElementsStrict().Count();
}
/// <summary>
/// Call <see cref="Container.Populate"/> and use strict method.
/// </summary>
[Test]
public void CorrectUsaOfStrictContract()
{
container.Populate();
Assert.AreEqual(0, container.GetElementsStrict().Count());
}
/// <summary>
/// Inconvenient contract - needs a local variable.
/// </summary>
[Test]
public void CarefulUseOfCarelessMethod()
{
var elements = container.GetElementsInconvenientCareless();
Assert.AreEqual(0, elements == null ? 0 : elements.Count());
}
/// <summary>
/// Inconvenient contract - duplicate call in order to use in context of an single expression.
/// </summary>
[Test]
public void LameCarefulUseOfCarelessMethod()
{
Assert.AreEqual(0, container.GetElementsInconvenientCareless() == null ? 0 : container.GetElementsInconvenientCareless().Count());
}
[Test]
public void LuckyCarelessUseOfCarelessMethod()
{
// INIT
var praySomeoneCalledPopulateBefore = (Action)(()=>container.Populate());
praySomeoneCalledPopulateBefore();
// ACT //ASSERT
Assert.AreEqual(0, container.GetElementsInconvenientCareless().Count());
}
/// <summary>
/// Excercise <see cref="ArgumentNullException"/> because of null passed to <see cref="Enumerable.Count{TSource}(System.Collections.Generic.IEnumerable{TSource})"/>
/// </summary>
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void UnfortunateCarelessUseOfCarelessMethod()
{
Assert.AreEqual(0, container.GetElementsInconvenientCareless().Count());
}
/// <summary>
/// Demonstrates the client code flow relying on returning null for empty collection.
/// Exception is due to <see cref="Enumerable.First{TSource}(System.Collections.Generic.IEnumerable{TSource})"/> on an empty collection.
/// </summary>
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void UnfortunateEducatedUseOfCarelessMethod()
{
container.Populate();
var elements = container.GetElementsInconvenientCareless();
if (elements == null)
{
Assert.Inconclusive();
}
Assert.IsNotNull(elements.First());
}
/// <summary>
/// Demonstrates the client code is bloated a bit, to compensate for implementation 'cleverness'.
/// We can throw away the nullness result, because we don't know if the operation succeeded or not anyway.
/// We are unfortunate to create a new instance of an empty collection.
/// We might have already had one inside the implementation,
/// but it have been discarded then in an effort to return null for empty collection.
/// </summary>
[Test]
public void EducatedUseOfCarefullMethod()
{
Assert.AreEqual(0, (container.GetElementsInconvenientCarefull() ?? Enumerable.Empty<Element>()).Count());
}
}
}
Buna milyar dolarlık hatam diyorum… O zamanlar, nesne yönelimli bir dilde referanslar için ilk kapsamlı yazım sistemini tasarlıyordum. Amacım, derleyici tarafından otomatik olarak yapılan kontrol ile tüm referans kullanımlarının kesinlikle güvenli olmasını sağlamaktı. Ama null referansı koyma cazibesine karşı koyamadım, çünkü uygulanması çok kolaydı. Bu, son kırk yılda muhtemelen milyar dolarlık ağrı ve hasara neden olan sayısız hataya, güvenlik açığına ve sistem çökmesine neden oldu. - Tony Hoare, ALGOL W. mucidi.
Genel olarak ayrıntılı bir bok fırtınası için buraya bakın null
. undefined
Başka bir ifadeye katılmıyorum null
, ama yine de okumaya değer. Ve null
sadece sorduğunuz durumda neden kaçınmanız gerektiğini açıklıyor . Özü, null
herhangi bir dilde özel bir durumdur. null
Bir istisna olarak düşünmek zorundasınız . undefined
bu şekilde farklıdır, tanımlanmamış davranışla ilgili kod çoğu durumda sadece bir hatadır. C ve diğer birçok dilde tanımlanmamış davranışlar vardır, ancak çoğunun dilde bunun için bir tanımlayıcısı yoktur.
Birincil yazılım mühendisliği hedefi olan karmaşıklığı yönetme perspektifinden , bir API istemcisine gereksiz siklomatik karmaşıklık yaymaktan kaçınmak istiyoruz . İstemciye null değeri döndürmek, başka bir kod dalının döngüsel karmaşıklık maliyetini döndürmek gibidir.
(Bu, birim test yüküne karşılık gelir. Boş toplama dönüş durumuna ek olarak, boş dönüş durumu için bir test yazmanız gerekir.)