2009-10-09 22 views
36

Son zamanlarda kullanabileceğimizi öğrendim ?? null kontrol etmek için operatör. Aşağıdaki kod örnekleri kontrol edin: Bu benim tüm proje kaynak deposu ve diğer açık kaynak projelerinin bazılarını kontrolneden tercih ediyoruz? ?? C# operatörü?

var res = (data==null) ? new data() : data ; 

tam olarak benzerdir

var res = data ?? new data(); 

. Ve bu ?? operatörü hiç kullanılmamış.

Sadece performans sorunları ya da bir şey gibi bunun arkasında bir neden olduğunu merak ediyorum?

DÜZENLEME: Sadece özyinelemeli & Anton yorumlarına dayanarak benim örnek kod güncelleştirilmiş

. Dikkatsiz bir yanlışlık. :(

+21

bir nedeni ppl farkında olmayabilir olduğunu! – vpram86

+1

"var res = (data! = Null)? Data: new data();" olmalıdır. Numaranızda –

+2

@Rubens, sadece aptalca ve doğru değil. – kenny

cevap

53

boş kaynaşabilecek operatör için null denetlerken, bu ana amacı budur çok daha nettir. Ayrıca zincirleme edilebilir. Bu operatör kontrol null sınırlı iken

object a = null; 
object b = null; 
object c = new object(); 
object d = a ?? b ?? c; //d == c. 

, üçlü operatördür değil. Örneğin

bool isQuestion = true; 
string question = isQuestion ? "Yes" : "No"; 

Onlara, bunun yerine üçlü operatörü kullanmak böylece insanlar sadece boş kaynaşabilecek operatörü farkında değildir düşünüyorum. içinizde C# bilmiyorum eğer öyleyse üçlü çoğu C tarzı dilde C# önce var ve dışarı ve/veya başka bir dilde programlanmış, te Rnary doğal bir seçimdir. Ancak null için denetliyorsanız, null coalesce işlecini kullanın, bunun için tasarlandı ve IL biraz daha iyi duruma getirildi.

İşte her

object a = null; 
object b = null; 
object c = null; 

object nullCoalesce = a ?? b ?? c; 

object ternary = a != null ? a : b != null ? b : c; 

object ifThenElse; 

if (a != null) 
    ifThenElse = a; 
else if (b != null) 
    ifThenElse = b; 
else if (c != null) 
    ifThenElse = c; 

İlk kullanımını karşılaştıran bir örnektir, sadece boş COALESCE için sözdizimi bakmak, bu yol nettir. Üçlü gerçekten kafa karıştırıcıdır. Şimdi IL at

Boş Coalesce bakalım Sadece

.entrypoint 
.maxstack 2 
.locals init (
    [0] object a, 
    [1] object b, 
    [2] object c, 
    [3] object nullCoalesce) 
L_0000: ldnull 
L_0001: stloc.0 
L_0002: ldnull 
L_0003: stloc.1 
L_0004: newobj instance void [mscorlib]System.Object::.ctor() 
L_0009: stloc.2 
L_000a: ldloc.0 
L_000b: dup 
L_000c: brtrue.s L_0015 
L_000e: pop 
L_000f: ldloc.1 
L_0010: dup 
L_0011: brtrue.s L_0015 
L_0013: pop 
L_0014: ldloc.2 
L_0015: stloc.3 
L_0016: ldloc.3 
L_0017: call void [mscorlib]System.Console::WriteLine(object) 
L_001c: ret 

Sadece

.entrypoint 
.maxstack 1 
.locals init (
    [0] object a, 
    [1] object b, 
    [2] object c, 
    [3] object ifThenElse) 
L_0000: ldnull 
L_0001: stloc.0 
L_0002: ldnull 
L_0003: stloc.1 
L_0004: newobj instance void [mscorlib]System.Object::.ctor() 
L_0009: stloc.2 
L_000a: ldloc.0 
L_000b: brfalse.s L_0011 
L_000d: ldloc.0 
L_000e: stloc.3 
L_000f: br.s L_001a 
L_0011: ldloc.1 
L_0012: brfalse.s L_0018 
L_0014: ldloc.1 
L_0015: stloc.3 
L_0016: br.s L_001a 
L_0018: ldloc.2 
L_0019: stloc.3 
L_001a: ldloc.3 
L_001b: call void [mscorlib]System.Console::WriteLine(object) 
L_0020: ret 

IL benim güçlü noktalarından biri değil sadece

.entrypoint 
.maxstack 2 
.locals init (
    [0] object a, 
    [1] object b, 
    [2] object c, 
    [3] object ternary) 
L_0000: ldnull 
L_0001: stloc.0 
L_0002: ldnull 
L_0003: stloc.1 
L_0004: newobj instance void [mscorlib]System.Object::.ctor() 
L_0009: stloc.2 
L_000a: ldloc.0 
L_000b: brtrue.s L_0016 
L_000d: ldloc.1 
L_000e: brtrue.s L_0013 
L_0010: ldloc.2 
L_0011: br.s L_0017 
L_0013: ldloc.1 
L_0014: br.s L_0017 
L_0016: ldloc.0 
L_0017: stloc.3 
L_0018: ldloc.3 
L_0019: call void [mscorlib]System.Console::WriteLine(object) 
L_001e: ret 

Sonra Else ise Üçlü, belki birisi benim cevabımı düzenleyebilir ve üzerinde genişleyebilir. Teorimi açıklayacağım ama kendimi ve başkalarını karıştırmamayı tercih ediyorum. LOC sayısı her üç için de benzerdir, ancak tüm IL operatörleri yürütmek için aynı süreyi almaz. Aklıma

+7

Bu * üçlü operatör değil, sadece bir * üçlü operatördür. Size atıfta bulunduğunuz ** koşullu operatör ** denir. iyi o C# tek üçlü operatör var: P –

+1

@Bob, biz boş değerlere sahip ... – RameshVel

+3

@divo başa zaman operatörün tüm iyidir coalesce ... hoş bir karşılaştırma bu. Ve koşullu işleci C# referansında kullanılan resmi terimdir;) – Lucas

6

bir nedeni bu operatör .NET 2.0 tanıtıldı yüzden .NET 1.1 kod bu olamaz olmasıdır.

Biz bu daha sık kullanıyor olmalıdır, size katılıyorum.

ref link

12

??Operatör (aynı zamanda null-coalescing operator olarak da bilinir), .NET 2.0 ve NULL türüne sahip olmasını sağlayan üçlü operatörden daha az bilinir. Bunu kullanmama nedenleri muhtemelen var olduğunu veya üçlü operatöre daha aşina olduklarını farketmemelidir.

boş kontrol üçlü operatör için iyidir tek şey değil, bu nedenle daha çok özel ihtiyaç için daha iyi bir alternatif gibi, örneğin bunun için bir yedek değil, Söylediğin. :)

1

Bunu sadece diğer dillerden bir alışkanlık olduğunu düşünüyorum. BİLDİĞİM KADARIYLA, ?? Operatör başka bir dilde kullanılmaz.

+2

Ben bu süper eski biliyorum ama yorum istedim ve o da sadece '//' ziyade '??' ile V5.10 itibarıyla Perl kullanılan söylüyorlar. '$ possibly_null_value // $ value_if_null': örnek olarak, ([Ara] (http://en.wikipedia.org/wiki/Null_coalescing_operator#Perl) alınan) –

0

I (Diğerleri zaten dokundu olarak)

var res = data ?? data.toString(); 

eşdeğer

var res = (data!=null) ? data : data.toString(); 
2

Bir nedeni olacağını düşündüm bilinç eksikliği olması muhtemeldir olurdu. Aynı zamanda (kendi durumumda olduğu gibi), bir kod tabanında olabildiğince aşağıya benzer şeyleri yapmak için yaklaşımların sayısını tutturmak da olabilirdi. Bu nedenle, üçlü operatörü, tüm bu durumlarda, tüm bu durumlarda, bir arada çalışır durumdaki tüm kompakt durumlar için kullanma eğilimindeyim.

Mesela ben bir kavramsal düzeyde aşağıdaki iki ifade yerine benzer bulmak: sürüm yapılarında gelen

return a == null ? string.Empty : a;  
return a > 0 ? a : 0; 
4

Tabanlı cevap

public object nullCoalesce(object a, object b, object c) 
{ 
    return a ?? b ?? c; 
} 
public object ternary(object a, object b, object c) 
{ 
    return a != null ? a : b != null ? b : c; 
} 
public object ifThenElse(object a, object b, object c) 
{ 
    if (a != null) 
     return a; 
    else if (b != null) 
     return b; 
    else 
     return c; 
} 

Bob's üzerine ... Bu IL olduğunu .. .

.method public hidebysig instance object nullCoalesce(
    object a, 
    object b, 
    object c) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.1 
    L_0001: dup 
    L_0002: brtrue.s L_000b 
    L_0004: pop 
    L_0005: ldarg.2 
    L_0006: dup 
    L_0007: brtrue.s L_000b 
    L_0009: pop 
    L_000a: ldarg.3 
    L_000b: ret 
} 

.method public hidebysig instance object ternary(
    object a, 
    object b, 
    object c) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.1 
    L_0001: brtrue.s L_000a 
    L_0003: ldarg.2 
    L_0004: brtrue.s L_0008 
    L_0006: ldarg.3 
    L_0007: ret 
    L_0008: ldarg.2 
    L_0009: ret 
    L_000a: ldarg.1 
    L_000b: ret 
} 

.method public hidebysig instance object ifThenElse(
    object a, 
    object b, 
    object c) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.1 
    L_0001: brfalse.s L_0005 
    L_0003: ldarg.1 
    L_0004: ret 
    L_0005: ldarg.2 
    L_0006: brfalse.s L_000a 
    L_0008: ldarg.2 
    L_0009: ret 
    L_000a: ldarg.3 
    L_000b: ret 
} 
İlgili konular