2016-05-17 13 views
22

Sadece 2010'dan 2015'e yükselttim. Ayrıca sıfır yayılımı olarak bilinen yeni null-conditional operator'u beğeniyorum. Bu, örneğin, kodunuzu basitleştirmek sağlar:Boş koşullu işleç bool değil bool için değerlendirir? beklendiği gibi

string firstCustomerName = customers?[0].Name; // null if customers or the first customer is null 

diğeri:

bir int geçerli sayısı ve daha önce herhangi nulls arasında ayrım yapmak bir Nullable<int> bile Enumerable.Count eğer döner döner
int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null 

. Oldukça sezgisel ve çok kullanışlı.

Ama neden (Bu false döndürür) beklendiği gibi bu derleme ve çalışma kapsamaz:

string text = null; 
bool contains = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase) >= 0; 

Ya dönmelidir bool? (öyle ki değil) derlemek ya da değil. Aslında ne var

+5

Kimler var? yeniden yazmak: int? indexof = text? .IndexOf ("Foo", StringComparison.CurrentCultureIgnoreCase); bool şunu içerir = indexof> = 0; ' –

+4

Bir?? = = operatör için oy kullanırdım.:) –

+0

@DStanley: Yani diğer [operatör kategorileri] (https://msdn.microsoft.com/en-us/library/aa691323 (v = vs.71) .aspx) birincil olanı içerir? İyiden daha çok zarar verirdi. –

cevap

28

string text = null; 
int? index = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase); 
bool contains = index >= 0; 

ve int? >= int tamamen yasal olduğunu.

o the documentation for the operator devletler orada bölündü sebebi "ise zincirinin yürütme geri kalanı boş durur şartlı üye erişimi ve indeks operasyon zincirinde bir operasyon döndürür. Diğer işlemler düşük önceliğe sahip ifadesinde devam ediyor. " Bu, .?'un yalnızca "bir değer yaratmadan" aynı önceliğe veya daha yüksek olan şeyleri değerlendireceği anlamına gelir.

the order of operator precedence'a bakarsanız, "İlişkisel ve Tür Deneme Operatörleri" nin listede çok daha düşük olduğunu göreceksiniz, böylece >= uygulanmadan önce değer oluşturulur.


GÜNCELLEME: Bu yorumların kadar getirildi Çünkü, burada bir null değeri ile uğraşırken >= ve diğer operatörler nasıl davrandıkları C 5. Spec bölümdür. Ben C# için bir belge 6.

7.3.7 Artırılan operatörler

Artırılan operatörleri bulamadık izin önceden tanımlanmış olan ve olmayan null değer türleri üzerinde işlem kullanıcı tanımlı operatörler de null ile kullanılacak Bu türlerin formları.
+ ++ - -- ! ~

bir operatör kaldırılmış bir şekilde, eğer var tekli operatörler için

  • : Kalkık operatörler aşağıda tarif gibi belirli gereksinimlerini karşılamak önceden tanımlanmış ve kullanıcı tanımlı operatörlerden inşa edilir işlenen ve sonuç türleri her ikiside null olmayan değer türleridir. Kaldırılan form, bir tek ekleyerek oluşturulmuş mu? işlenen için değiştirici ve sonuç türleri. İşlenen kullanıcı boşsa, kaldırılan operatör boş değer üretir.Aksi halde, kaldırılan operatör işleneni açar, temel operatörünü uygular ve sonucu sarar. ikili operatörler
    için

  • + - */% & |^<< >>

    bir operatör kaldırılmış bir şekilde işlenen ve sonuç tipleri olmayan tüm null değer türleri ise bulunmaktadır. Kaldırılan formu tarafından bir tek ekleyerek inşa edilir? her işlenen için değiştirici ve sonuç türü. Kaldırılan işleci, bir veya her iki işlenen de boşsa (& ve bool? Türünün | operatörleri, §7.11.3'te açıklandığı şekilde) istisnası boş değer üretir. Aksi halde, kaldırılan operatör işlenenleri açar, temel operatörü uygular ve sonucu sarar. işlenen tipleri her ikisi NULL olmayan bir değer türleri ve eğer sonuç tipi BOOL ise
    == !=

    bir operatör kaldırılmış bir şekilde var olan eşitlik işlemleri için

  • . Kaldırılan formu, bir tek ekleyerek oluşturulur? Her işlenen için değiştirici türü. Kaldırılan işleç, iki boş değerle eşit ve boş olmayan bir değere eşit olmayan bir değeri dikkate alır. Her iki işlenen de boş değilse, kaldırılan operatör işlenenleri açar ve bool sonucunu üretmek için alttaki işlecini uygular. ilişkisel operatörler
    < > <= >=

    bir operatör kaldırılmış bir şekilde işlenen tipleri her ikisi Null değer türleri ise vardır ve sonuç tipi BOOL ise For

  • . Kaldırılan formu, bir tek ekleyerek oluşturulur? Her işlenen için değiştirici türü. Kaldırılan işleç, işlenenlerinden biri veya her ikisi de boşsa false değerini üretir. Aksi halde, kaldırılan operatör, işlenenleri çözer ve bool sonucunu üretmek için alttaki operatörü uygular.

    var x = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase); 
    bool contains = x >= 0; 
    

    Yani yazarak hala doğrudur:

+0

, '> =' zaman 'Nullable' aslında null operatörünün davranış nedir? Basit açısından njzk2 @ – njzk2

+0

, her iki tarafında veya her iki tarafında '> =' her zaman yanlış bir boş dönecektir ise. Tam özellik için güncellememi görün. –

+0

Teşekkürler @ScottChamberlain – njzk2

3

Eğer x bir int? olduğunu görüyoruz, bu kodu kullanın ve x üzerine gelirsek.

x >= 0'a bakalım: int? >= int. Görünürde, null ve null olmayan yapıları arasında bir operatör var. İşte bu yüzden çalışıyor.

IL'ye bakarsanız, aslında HasValue ve GetValueOrDefault() numaralarını görürsünüz. Bunu yapan bir operatör var sanırım, ama ben referans kaynağında bulamadım, bu yüzden CLR veya derleyici:

instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() 

... 
instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue() 
+1

Doğru, ancak null koşullu operatörün, bir bool? Döndüren '> = operatörünü içerdiği olabilirdi. Ama sanırım bunun anlamı, "_" ifadesinde daha düşük önceliğe sahip diğer işlemler ile devam ediyor "_] (https://msdn.microsoft.com/en-us/library/dn986595.aspx). –