Güncelleme: Visual Studio 2015'ten başlayarak, C # derleyicisi (dil sürümü 6) artık ?.
operatörü tanıyor ve bu da "derin boşluk denetimini" çocuk oyuncağı haline getiriyor. Ayrıntılar için bu yanıta bakın.
Bu silinmiş cevabın önerdiği gibi kodunuzu yeniden tasarlamanın yanı sıra
, başka (korkunç da olsa) bir seçenek, bu derin mülk araması sırasında try…catch
bir ara NullReferenceException
meydana gelip gelmediğini görmek için bir blok kullanmak olabilir .
try
{
var x = cake.frosting.berries.loader;
...
}
catch (NullReferenceException ex)
{
// either one of cake, frosting, or berries was null
...
}
Şahsen bunu aşağıdaki nedenlerden dolayı yapmazdım:
- Hoş görünmüyor.
- Normal çalışma sırasında sık sık olmasını beklediğiniz bir şeyi değil, istisnai durumları hedeflemesi gereken istisna işlemeyi kullanır.
NullReferenceException
s muhtemelen hiçbir zaman açıkça yakalanmamalıdır. ( Bu soruya bakın .)
Öyleyse, bazı uzatma yöntemlerini kullanmak mümkün mü yoksa bir dil özelliği mi, [...]
Bu neredeyse kesin (biçiminde C # 6 kullanılabilen bir dil özelliği olması gerekir .?
ve ?[]
C # zaten daha sofistike tembel muayeneden geçmiş sürece, operatörler) veya muhtemelen de değildir yansıması (kullanmak istemiyorsanız performans ve tip güvenliği açısından iyi bir fikir).
cake.frosting.berries.loader
Bir işleve basitçe geçiş yapmanın bir yolu olmadığından (değerlendirilir ve boş bir referans istisnası atılır), aşağıdaki şekilde genel bir arama yöntemi uygulamanız gerekir: Bir nesneyi ve özelliklerin adlarını alır yukarı Bak:
static object LookupProperty( object startingPoint, params string[] lookupChain )
{
// 1. if 'startingPoint' is null, return null, or throw an exception.
// 2. recursively look up one property/field after the other from 'lookupChain',
// using reflection.
// 3. if one lookup is not possible, return null, or throw an exception.
// 3. return the last property/field's value.
}
...
var x = LookupProperty( cake, "frosting", "berries", "loader" );
(Not: kod düzenlendi.)
Böyle bir yaklaşımla hızlıca birkaç sorun görürsünüz. İlk olarak, herhangi bir güvenlik türü ve basit bir türdeki özellik değerlerinin olası kutulamasını elde edemezsiniz. İkincisi, bir null
şeyler ters giderse geri dönebilirsiniz ve arama işlevinizde bunu kontrol etmeniz gerekecek veya bir istisna atarsınız ve başladığınız yere geri dönersiniz. Üçüncüsü, yavaş olabilir. Dördüncüsü, başladığından daha çirkin görünüyor.
[...] veya bu sadece kötü bir fikir mi?
Ya şununla kalırdım:
if (cake != null && cake.frosting != null && ...) ...
ya da Mehrdad Afshari'nin yukarıdaki cevabı ile devam edin.
Not: Bu cevabı yazdığımda, lambda fonksiyonları için ifade ağaçlarını açıkça düşünmemiştim; Bu yöndeki bir çözüm için örneğin @driis'in cevabına bakınız. Aynı zamanda bir tür düşünceye dayalıdır ve bu nedenle daha basit bir çözüm ( if (… != null & … != null) …
) kadar iyi performans göstermeyebilir , ancak sözdizimi açısından daha iyi değerlendirilebilir.