2010-06-23 24 views
8

C# içindeki ?? işleci, değerlendirirken kısa devreye mı sarılıyor? myObject boş olmayan olduğunda"???" operatörü kısa dolaşımını kullanıyor mu?

var result = myObject ?? ExpressionWithSideEffects(); 

, ExpressionWithSideEffects() sonucu kullanılmaz, ama tamamen atlanır ExpressionWithSideEffects() olacak?

cevap

7

Evet öyle. Her zamanki gibi, C# dil belirtimi, kesin kaynağıdır. C 3. spec itibaren

, bölüm 7.12 (v4 Spec burada gerçekten alakalı olmayan dinamik detaya gider yerine 4 v3):

ifade a ?? b tipi hangi bağlıdır örtük dönüşümler, işlenenlerin türleri arasında kullanılabilir. Tercih sırasına göre, a ?? b A, A veya B'dir, burada A, a'dır, B, b'nin tipidir (b'nin bir türü vardır) ve A A, A'nın null bir tür olması durumunda A'nın temel tipidir veya aksi takdirde A'dır. . Bir değilse

  • null bir tipi ya da bir referans tipi, bir derleme hatası oluşur: Özel olarak ise, a ?? b işlenir.
  • A, null bir türse ve b ile A0 arasında örtük bir dönüşüm varsa, sonuç türü A0'dır. çalışma zamanında, ilk değerlendirilir. Bir boş değilse, A0 yazmak için bir sarılmış ve bu sonuç olur. Aksi takdirde, b değerlendirilir ve A0 türüne dönüştürülen ve sonuç olur.
  • Aksi takdirde, örtük bir dönüşüm b'den A'ya varsa, sonuç türü A'dır. Çalışma zamanında, ilk önce bir değerlendirilir. Eğer bir null değilse, sonucu olur. Aksi takdirde, b değerlendirilir ve A türüne dönüştürülen ve sonuç olur.
  • Aksi takdirde, b B türünde ve A0 ile B arasında örtük bir dönüşüm varsa, sonuç türü B'dir. Çalışma zamanında, a ilk olarak değerlendirilir. A, değilse, A0 (A ve A0 aynı türde değil) yazıp B türüne dönüştürülür ve bu sonucuna dönüşür. Aksi halde, b değerlendirilir ve sonuç olur.Aksi takdirde, a ve b uyumlu değildir ve bir derleme zamanı hatası oluşur.

, ikinci, üçüncü ve dördüncü mermilerin ilgili olanlardır.


Eğer kullanacağınız başına derleyici gerçeğin fiili kaynak olup olmadığı konusunda vardı edilecek bir felsefi tartışma var ... o yapmak demek ne bir dili hakkında gerçektir veya şu anda kullanıyor mu?

+0

Ayak notuna ... Bence hepimiz Eric Lippert'in tadını çıkarıyoruz :) –

+1

@Matthew: Pek çok nedenden biri, evet. Eric'in ilginç bir yönü, hem * hem de * derleyicinin insan enkarnasyonu olarak hareket edebilmesidir ... –

10

Evet, kısa devre yapıyor.

İşte LINQPad içinde test etmek için bir parçacık İşte:

string bar = "lol"; 
string foo = bar ?? string.Format("{2}", 1); 
foo.Dump(); 
bar = null; 
foo = bar ?? string.Format("{2}", 1); 
foo.Dump(); 

birinci kaynaşabilecek ikincisi atmak (biçim dizesi geçersiz) yok iken bir durum üretiliyor olmadan çalışır.

+0

saçma, Kendimi olay ufkuna çekiyorum hissedebiliyorum! – Will

0

Bu nedenle birim testimiz var.

[TestMethod] 
    public void ShortCircuitNullCoalesceTest() 
    { 
     const string foo = "foo"; 
     var result = foo ?? Bar(); 
     Assert.AreEqual(result, foo); 
    } 

    [TestMethod] 
    [ExpectedException(typeof(ArgumentException))] 
    public void ShortCircuitNullCoalesceFails() 
    { 
     const string foo = null; 
     var result = foo ?? Bar(); 
    } 

    private static string Bar() 
    { 
     throw new ArgumentException("Bar was called"); 
    } 

Bunlar en iyi test adları değil, ancak siz bu fikri anlıyorsunuz. Boş birleştirme operatörü kısa devrelerini beklendiği gibi gösterir.

+0

Ve ben ArgumentException garip bir seçim olduğunu anlıyorum, sadece akla ilk gelen özel istisna türü oldu. – CaffGeek

+3

Bu yüzden ünite testimiz yok. Bu yüzden dil şartlarımız var. Özellikle, ünite testi yaptık, ancak dil spesifikasyonu olmasaydı, yalnızca test edilmek durumunda ne yapıldığını bilirdik. Bununla birlikte, dil spesifikasyonuna sahip olsaydık ancak ünite testi yapmazsak, genel olarak dilin ne anlama geldiğini hala biliyor olurduk. Kuşkusuz ünite testi derleyicinin dil özelliklerini uygulayabildiğini doğrulamaya yardımcı olur ... ama böyle bir soru için her zaman bir birim testinden ziyade spesifikasyonlara ulaşmak isterim. –

+0

@Jon Skeet, touche. Hala emin olmadığım şeyleri doğrulamak için hızlı testler yazmaktan hoşlanıyorum. Her zaman yanında olmayacağım. Ve derleyicinin spekülasyonu yanlış uyguladığı her zaman mümkündür ... – CaffGeek

İlgili konular