2013-07-09 8 views
5
DateTime? date = null; 
string tmp = "a" + "(" + date ?? "blablabla" + ")"; 

Console.WriteLine(tmp); 

यह कुछ करीब प्रिंट करेगा: 'a ('क्या यह विजुअल स्टूडियो 2010 कंपाइलर में एक बग है?

क्या यह null-coalescing operator के साथ एक बग है? यदि मैं date ?? "blablabla" कोष्ठक में डालता हूं, तो इसे त्रुटि के रूप में रेखांकित किया जाता है।

+3

'तारीख को घेरना नहीं है ?? "blablabla" 'ब्रेसिज़ के साथ, लेकिन कोष्ठक के साथ, और हमें बताएं कि क्या कुछ बदलता है। –

+14

"क्या यह एक कंपाइलर बग है?" जवाब के 99.99% उत्तर ** नहीं ** है। –

+0

मुझे केवल एक ही कंपाइलर बग मिला है, और यह 20 साल पहले था। और यह पुष्टि करना आसान था कि कॉल को उस विशिष्ट कंपाइलर के एक संस्करण में खराब कोड में संकलित किया गया था, फिर भी पहले और बाद के संस्करणों में अलग-अलग (और सही ढंग से) व्यवहार किया गया था। यह ऐसा कोई मामला नहीं है। – jwenting

उत्तर

5

सबसे पहले, आपको always assume it's your fault होना चाहिए, संकलक की गलती नहीं; select isn't broken। क्या आप ईमानदारी से सोचते हैं कि ?? ऑपरेटर के विजुअल स्टूडियो 2010 कार्यान्वयन का परीक्षण नहीं किया गया है? जब आपको ऐसा कुछ मिलता है जो आपकी उम्मीदों से मेल नहीं खाता है, तो अपनी अपेक्षाओं की जांच करें। मैनुअल प्राप्त करें, और सुनिश्चित करें कि आपवास्तव में समझने के लिए क्या लगता है। इस मामले में, भाषा विनिर्देश खोलें।

यदि आप specification के §1.4 पर जाते हैं, तो आपको एक तालिका दिखाई देगी जो ऑपरेटरों को प्राथमिकता समूह में समूहित करती है; आप इसे online भी ढूंढ सकते हैं। विशेष रूप से, नल कोलेसिंग ऑपरेटर ??नीचे के पास है, केवल कम सशर्त टर्नरी ऑपरेटर और असाइनमेंट और => से ऊपर है। यह अतिरिक्त योजक है। इस प्रकार, आपके बयान

string tmp = "a" + "(" + date ?? "blablabla" + ")"; 

रूप

string tmp = (("a" + "(" + date) ?? ("blablabla" + ")")); 

संकलक द्वारा इलाज किया जाता है मैं पूरी तरह से पंडिताऊ होने के लिए और नहीं जा रहा हूँ भी पहले additive अभिव्यक्ति बीच में लिखना। के बाद से है कि बयान में अभिव्यक्ति के बाएं साइड कभी नहीं अशक्त, बेशक यह हमेशा प्रदान करती है "a(" (या "a(" + date.ToString() जब date.HasValue सच है) tmp है।

मुख्य मुद्दा यह है कि आप क्या हो रहा जाना चाहिए कि आप मैनुअल के खिलाफ सत्यापित किया जाना चाहिए था के रूप में एक गलत उम्मीद था।

यदि मैं date ?? "blablabla" कोष्ठक में डालता हूं, तो इसे त्रुटि के रूप में रेखांकित किया जाता है।

बेशक यह है। क्या आपने त्रुटि संदेश भी पढ़ा था? यह शायद आपको बताता है कि आप DateTime? और string पर नहीं कर सकते हैं क्योंकि DateTime? और string के बीच किसी भी दिशा में कोई अंतर्निहित रूपांतरण नहीं है। यह भी भाषा विनिर्देश में शामिल है; §7.13 देखें।आपको यह संदेश पढ़ना होगा और पर प्रतिक्रिया दें। कुछ शब्दार्थ क्या आप रहे व्यक्त करने के लिए कोशिश कर रहा के बराबर पाने के लिए आपको सशर्त त्रिगुट ऑपरेटर का सहारा लेना होगा:

date.HasValue ? date.ToString() : "blablabla" 

और फिर कोष्ठकों में है कि पूरी बात लपेट क्योंकि सशर्त त्रिगुट ऑपरेटर बहुत कम प्राथमिकता है।

अंत में, मुझे आपके कोड का सही ढंग से संश्लेषित संस्करण मिलता है बदले में, पढ़ने के लिए मजेदार नहीं, और शायद बनाए रखने के लिए सुखद नहीं है। बस इसे सरल, कृपया सुनिश्चित:

var tmp = String.Format("a({0})", 
         date.HasValue ? date.ToString() : "blablabla"); 

अब यह है तो स्पष्ट क्या चल रहा है और क्या होने वाला है। मुझे समझने के लिए पर विचार नहीं करना है। आपको सामना करने वाली मुश्किल समस्याओं के लिए अपनी सोच सहेजें।

: सावधान रहें। पहले मूल्यांकन किए गए आंकड़ों को सही ढंग से समझने का प्रयास करने से पहले हमें date.ToString (जिसमें उच्चतम प्राथमिकता है) को एक विधि कॉल में जोड़ने की आवश्यकता होगी।

+2

यह उत्तर चयनित एक से बेहतर है। –

0

इसका कारण यह है date एक स्ट्रिंग नहीं है और ?? ऑपरेटर एक आम आधार प्रकार निर्धारित नहीं कर date और "blablabla" के लिए सबसे अधिक संभावना है। (date.ToString() ?? "blablabla") आज़माएं। लेकिन यह आपकी ज़रूरत को पूरा नहीं करेगा क्योंकि date.ToString() कभी भी null नहीं होगा।

string tmp = "a" + "(" + (date ?? DateTime.Now) + ")"; 

काम करना चाहिए।

+0

प्लस, यदि 'date'' null' है, और आप उस पर 'ToString()' को कॉल करने का प्रयास करते हैं, तो आपको 'NullReferenceException'' मिलेगा (हम्म, जो केवल संदर्भ प्रकारों के लिए शून्य हो सकता है - और 'डेटटाइम' एक वैल्यू टाइप है, इसलिए इसके लिए नामुमकिन वर्ग-आधारित के बजाय मूल्य-प्रकार 'Nullable ' होगा - तो शायद यह ठीक रहेगा?)। – fourpastmidnight

+0

@fourpastmidnight आपका सुझाव सही है - ((डेटटाइम?) शून्य)। ToString() त्रुटियों के बिना निष्पादित करता है। – Artemix

+0

कूल, इसके लिए धन्यवाद। – fourpastmidnight

2

"blablabla" एक तिथि नहीं है, इसलिए आप date? सेट करने के लिए उपयोग नहीं कर सकते हैं।


string tmp = "a" + "(" + date ?? "blablabla" + ")"; 

string tmp = ("a" + "(" + date) ?? ("blablabla" + ")"); 

जो वह जगह है जहाँ अपने a( से आ रहा है के बराबर है।


हालांकि

string tmp = "a" + "(" + (date ?? DateTime.Now) + ")"; 

या इसी तरह के काम करना चाहिए।

0

यह नल-कोलेसिंग ऑपरेटर के साथ एक बग नहीं है।

यह operator precedence है:

("a" + "(" + date.ToString()) ?? ("blablabla" + ")") 

और ("a" + "(" + date.ToString()) अशक्त नहीं है:

"a" + "(" + date ?? "blablabla" + ")" 

के समान है।

8

Null-coalescing operator??+ ऑपरेटर की तुलना में कम पूर्वता है, तो आपके कोड सभी गैर-स्ट्रिंग ऑपरेंड पर .ToString() फोन करके

string tmp = ("a" + "(" + date) ?? ("blablabla" + ")"); 

के बाद से एक तार के साथ + ऑपरेशन में सब कुछ एक स्ट्रिंग पैदा करता है (के बराबर है), आपका कोड हमेशा "a(" स्ट्रिंग का उत्पादन करेगा।

+0

"प्राथमिकता" पर "प्राथमिकता", मैं कहूंगा। –

+0

यह भी ध्यान रखना महत्वपूर्ण है कि एक गैर-शून्य स्ट्रिंग नल-नल स्ट्रिंग में नल-नल स्ट्रिंग में त्रुटि या शून्य के बजाय, इसलिए '+ date' प्रभावी ढंग से नो-ऑप है। – Servy

1

C# Language Specification §1.4 से

निम्नलिखित तालिका सारांशित सी # के ऑपरेटरों, श्रेष्ठता के क्रम में ऑपरेटर श्रेणियों लिस्टिंग उच्चतम से न्यूनतम। में ऑपरेटरों को समान श्रेणी में समान प्राथमिकता है।

यह कहता है कि Additive operators शून्य कोलेसिंग ऑपरेटर की तुलना में अधिक प्राथमिकता है।

तो, +?? से अधिक प्राथमिकता है और यही कारण है कि "blablabla" + ")" अभिव्यक्ति पहले काम करती है।

और datenull है, कथन इस प्रकार काम करता है;

string tmp = "a" + "(" + null; 

और सामान्य रूप से परिणाम a(

3

यहाँ सिर्फ एक और संस्करण होगा:

DateTime? date = null; 
string tmp = string.Format("a({0})", 
          date.HasValue ? date.ToString() : "blablabla"); 

मैं वास्तव में संयोजन के बजाय string.Format प्यार करता हूँ।

+1

मैं भी करता हूं; मैं सभी के लिए सबसे सरल अभिव्यक्तियों के लिए यह अधिक पठनीय और रखरखाव कोड की ओर जाता है। – jason

संबंधित मुद्दे