2010-06-23 20 views
8

क्या ?? सी # में ऑपरेटर मूल्यांकन करते समय शॉर्टरक्यूटिंग का उपयोग करता है?क्या `` ?? `ऑपरेटर शॉर्टरक्यूटिंग का उपयोग करता है?

var result = myObject ?? ExpressionWithSideEffects(); 

जब myObject में गैर-शून्य है, ExpressionWithSideEffects() का नतीजा नहीं किया जाता है, लेकिन पूरी तरह से छोड़ दिया ExpressionWithSideEffects() होगा?

उत्तर

7

हां यह करता है। हमेशा के रूप में, सी # भाषा विनिर्देश निश्चित स्रोत है।

सी # 3 युक्ति से, खंड 7.12 (बजाय 4 v3, के रूप में v4 कल्पना गतिशील विवरण जो यहाँ वास्तव में प्रासंगिक नहीं हैं में चला जाता है):

अभिव्यक्ति a ?? b के प्रकार पर निर्भर करता है जो निहित रूपांतरण ऑपरेंड के प्रकारों के बीच उपलब्ध हैं। वरीयता के क्रम में, एक प्रकार का ?? बी ए 0, ए, या बी है, जहां ए ए का प्रकार है, बी बी का प्रकार है (बशर्ते बी में एक प्रकार है), और ए 0 अंतर्निहित प्रकार ए है यदि ए एक शून्य प्रकार है, या अन्यथा ।

  • एक नल प्रकार या एक संदर्भ प्रकार, एक संकलन समय त्रुटि होती है एक नहीं है: विशेष रूप से, a ?? b रूप इस प्रकार संसाधित किया जाता है।
  • यदि ए एक नामुमकिन प्रकार है और बी से ए 0 से एक अंतर्निहित रूपांतरण मौजूद है, तो परिणाम प्रकार A0 है। रन-टाइम पर, पहले मूल्यांकन किया जाता है। यदि शून्य नहीं है, तो ए 0 टाइप करने के लिए अनचाहे है, और यह परिणाम बन जाता है। अन्यथा, बी का मूल्यांकन किया गया है और ए 0 टाइप करने के लिए परिवर्तित किया गया है, और यह परिणाम परिणाम बन जाता है।
  • अन्यथा, यदि कोई अंतर्निहित रूपांतरण बी से ए में मौजूद है, तो परिणाम प्रकार ए रन-टाइम पर, पहले मूल्यांकन किया जाता है। यदि कोई शून्य नहीं है, तो परिणाम बन जाता है। अन्यथा, बी का मूल्यांकन किया जाता है और टाइप ए में परिवर्तित हो जाता है, और यह परिणाम परिणाम बन जाता है।
  • अन्यथा, यदि बी में एक प्रकार बी है और एक अंतर्निहित रूपांतरण A0 से बी से मौजूद है, तो परिणाम प्रकार बी है। रन-टाइम पर, का पहला मूल्यांकन किया जाता है। यदि शून्य नहीं है, तो A0 टाइप करने के लिए अनचाहे है (जब तक ए और ए 0 समान प्रकार नहीं हैं) और प्रकार बी में परिवर्तित किया गया है, और यह परिणाम बन गया है। अन्यथा, बी मूल्यांकन किया गया है और परिणाम बन गया है।
  • अन्यथा, ए और बी असंगत हैं, और एक संकलन-समय त्रुटि होती है।

दूसरा, तीसरा और चौथा गोलियां प्रासंगिक हैं।


वहाँ एक दार्शनिक चर्चा है कि क्या संकलक आपको उपयोग के लिए हो वास्तविक सच्चाई का स्रोत है के बारे में किया जा रहा है ... एक भाषा यह क्या मतलब करना है के बारे में सच है या वर्तमान में यह है?

+0

पैर नोट पर ... मुझे लगता है कि हम सभी एरिक लिपर्ट का आनंद ले रहे हैं :) –

+1

@ मैथ्यू: कई कारणों में से एक, हां। एरिक का एक दिलचस्प पहलू यह है कि वह spec * और * कंपाइलर दोनों के मानव अवतार के रूप में कार्य कर सकता है ... –

10

हां, यह शॉर्ट सर्किट करता है।

यहाँ LINQPad में परीक्षण करने के लिए एक टुकड़ा है:

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

पहले सम्मिलित एक अपवाद फेंक जबकि दूसरा एक करता है थ्रो (प्रारूप स्ट्रिंग अमान्य है) के बिना काम करता है।

+0

बकवास, मैं खुद को घटना क्षितिज में खींच लिया जा सकता है! – Will

0

यही कारण है कि हमारे पास यूनिट परीक्षण है।

[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"); 
    } 

ये सर्वोत्तम परीक्षण नाम नहीं हैं, लेकिन आपको विचार मिलता है। यह दिखाता है कि अपेक्षित के रूप में शून्य coalesce ऑपरेटर शॉर्ट सर्किट।

+0

और मुझे एहसास हुआ कि ArgumentException एक अजीब विकल्प था, यह केवल वसंत के लिए पहला अपवाद प्रकार था। – CaffGeek

+3

यही कारण है कि हमारे पास यूनिट परीक्षण नहीं है। यही कारण है कि हमारे पास भाषा विनिर्देश हैं। विशेष रूप से, अगर हमारे पास यूनिट परीक्षण था लेकिन कोई भाषा नहीं थी, तो हम केवल यह जान लेंगे कि परीक्षण के मामले में क्या करना है। अगर हमारे पास भाषा का नमूना था लेकिन कोई इकाई परीक्षण नहीं था, हालांकि, हम अभी भी जानते होंगे कि सामान्य मामले में भाषा का क्या अर्थ है। स्वीकार्य रूप से इकाई परीक्षण यह सत्यापित करने में मदद करता है कि संकलक वास्तव में भाषा की कल्पना लागू करता है ... लेकिन मैं हमेशा इस तरह के प्रश्नों के लिए यूनिट परीक्षण की तुलना में spec तक पहुंचता हूं। –

+0

@ जोन स्कीट, स्पर्श करें। मैं अभी भी उन चीजों को सत्यापित करने के लिए त्वरित परीक्षण लिखना पसंद करता हूं जिनके बारे में मुझे यकीन नहीं है। मैं इसे जरूरी नहीं रखूंगा। और यह हमेशा संभव है कि संकलक ने spec को अनुचित रूप से कार्यान्वित किया ... – CaffGeek