2009-05-13 14 views
204

मैं बस एक अजीब त्रुटि में आया:निरर्थक प्रकार और टर्नरी ऑपरेटर: `क्यों है? 10: शून्य 'वर्जित?

private bool GetBoolValue() 
{ 
    //Do some logic and return true or false 
} 

फिर, किसी अन्य विधि में, इस तरह कुछ:

int? x = GetBoolValue() ? 10 : null; 

सरल, यदि विधि सही होती है, तो Nullable int x को 10 असाइन करें। अन्यथा, nullable int को शून्य दें। हालांकि, संकलक शिकायत करता है:

Error 1 Type of conditional expression cannot be determined because there is no implicit conversion between int and <null> .

क्या मैं पागल हो रहा हूँ?

+2

हो सकता है कि इस संकलक के भविष्य के संस्करण में सुधार दिया जाएगा क्योंकि, वहाँ वास्तव में 'int' और '' के बीच एक अंतर्निहित रूपांतरण है और वह है 'पूर्णांक?' –

+0

@ ब्रूनो, यह कहने के लिए अलग कैसे है "वास्तव में [किसी भी प्रकार] और [किसी अन्य प्रकार] और यह 'ऑब्जेक्ट' 'के बीच एक अंतर्निहित रूपांतरण है? क्या आपको लगता है कि वे संकलक के भविष्य के संस्करण में भी "सही" करेंगे? उदाहरण के लिए: ऑब्जेक्ट x = GetBoolValue()? (ऑब्जेक्ट) "foo": (ऑब्जेक्ट) डेटटाइम.अब; – LukeH

+2

कल्पना करें कि कंपाइलर इतना स्मार्ट था कि "ठीक है, हम पहले प्रकार (int) का उपयोग नहीं कर रहे हैं, इसलिए हम इस अभिव्यक्ति के परिणाम के लिए उपयोग कर सकते हैं कि हम एक और प्रकार की तलाश करेंगे।" यदि आप "कंसोल लिखते हैं तो आपको क्या मिलेगा। (राइटिकेट()? 5.6: शून्य) .GetType()। ToString());"? क्या आप फ्लोट करेंगे? या डबल? या वस्तु? या एक उपयोगकर्ता परिभाषित वर्ग फ्लोट से अंतर्निहित रूपांतरण के साथ? संकलक कैसे पता चलेगा कि किस प्रकार का चयन करना है, क्योंकि यह अभिव्यक्ति में कोई नहीं चुन सकता है? – mquander

उत्तर

336

संकलक पहले दाएँ हाथ अभिव्यक्ति का मूल्यांकन करने की कोशिश करता है:

आप के साथ बेहतर किस्मत हो सकता है

GetBoolValue() ? 10 : null 

10 एक int शाब्दिक (नहीं int?) और null है , ठीक है, null। उन दोनों के बीच त्रुटि संदेश इसलिए कोई अंतर्निहित रूपांतरण नहीं है।

आप उसके बाद निम्न यह संकलित क्योंकि int? और null के बीच एक अंतर्निहित रूपांतरण है वहाँ (# 1) और int और int? के बीच से एक के लिए दाएँ हाथ अभिव्यक्ति को बदलते हैं (# 2, # 3)।

GetBoolValue() ? (int?)10 : null // #1 
GetBoolValue() ? 10 : (int?)null // #2 
GetBoolValue() ? 10 : default(int?) // #3 
+6

आप 'नया int?() 'भी लिख सकते हैं। – SLaks

+36

या इससे भी बेहतर IMHO: 'डिफ़ॉल्ट (int?)' – Lucero

+1

हां, कंपाइलर को इस सुराग की आवश्यकता है इससे पहले ** ** ** int '10 को 'int' पर लपेटें। ध्यान दें कि एक और संभावना ** बॉक्स ** 'int' 10 को बेस क्लास या 'System.Int32'' के इंटरफ़ेस के लिए होगी। उदाहरण के रूप में 'GetBoolValue()? (IFormattable) 10: शून्य // # 1 बी' या 'GetBoolValue()? 10: (IFormattable) शून्य // # 2 बी 'ठीक रहेगा। यह संभावना एक कारण हो सकता है कि वे नलिका-रैपिंग स्वचालित क्यों नहीं बनाते हैं। चूंकि दोनों रैपिंग और मुक्केबाजी सामान्य रूप से _implicit_ रूपांतरण होते हैं। वह दोनों int है? चर = 10; 'और' IFormattable चर = 10; 'कानूनी हैं (पूर्व लपेटें, बाद के बक्से)। –

30

इस प्रयास करें:

int? x = GetBoolValue() ? 10 : (int?)null; 

असल में क्या हो रहा है कि सशर्त ऑपरेटर अभिव्यक्ति की "वापसी प्रकार" निर्धारित करने में असमर्थ है। चूंकि संकलक निहित रूप से निर्णय लेता है कि 10 एक int है, तो यह निर्णय लेता है कि इस अभिव्यक्ति का वापसी प्रकार int होगा। चूंकि intnull (सशर्त ऑपरेटर का तीसरा ऑपरेंड) नहीं हो सकता है, इसलिए यह शिकायत करता है।

null को Nullable<int> पर कास्ट करके हम संकलक को स्पष्ट रूप से बता रहे हैं कि इस अभिव्यक्ति का रिटर्न प्रकार Nullable<int> होगा। आप 10 से int? पर भी आसानी से डाले जा सकते थे और इसका भी असर पड़ा था।

+0

मुझे पता है कि मैं इसके आसपास काम कर सकता हूं, मैं उत्सुक हूं कि यह क्यों हो रहा है? – BFree

3
int? x = GetBoolValue() ? 10 : (int?)null; 

कारण आप देख इस वजह से पर्दे के पीछे आप Nullable का उपयोग कर रहे हैं और आप सी # है कि आपके "अशक्त" Nullable की एक अशक्त उदाहरण है बताने के लिए की जरूरत है।

+0

दोह! एंड्रयू को अपना पहला मिला। उसे +1। –

4

इनमें से किसी एक का प्रयास करें:

int? x = GetBoolValue() ? (int?)10 : null; 

int? x = GetBoolValue() ? 10 : (int?)null; 
+0

हम एक और जोड़ सकते हैं: int? एक्स = GetBoolValue()? 10: नया int?(); – Eniola

3

बस एक explict वर्णक जोड़ने।

int? x = GetBoolValue() ? 10 : (int?)null; 

यह त्रिगुट ऑपरेटर भ्रमित हो जाता है वह यह है कि - दूसरा तर्क एक पूर्णांक है और इसलिए तीसरा तर्क एक पूर्णांक होना करने के लिए, भी exspected है, और अशक्त फिट नहीं करता है।

4

समस्या यह है कि टर्नरी ऑपरेटर आपके पहले पैरामीटर असाइनमेंट के आधार पर प्रकार का उल्लंघन कर रहा है ... इस मामले में 10, जो एक int है, एक शून्य नहीं है।

int? x = GetBoolValue() (int?)10 : null; 
3

ऐसा इसलिए है क्योंकि संकलक सशर्त ऑपरेटर के दूसरे और तीसरे ऑपरेंड द्वारा निर्धारित करता है, न कि आप परिणाम को निर्दिष्ट करते हैं। एक पूर्णांक और शून्य संदर्भ के बीच कोई प्रत्यक्ष कलाकार नहीं है जिसे संकलक प्रकार निर्धारित करने के लिए उपयोग कर सकते हैं।

12

संयोग से, सी # कंपाइलर का माइक्रोसॉफ्ट कार्यान्वयन वास्तव में सशर्त ऑपरेटर का प्रकार विश्लेषण बहुत सूक्ष्म और रोचक (मेरे लिए) तरीके से गलत हो जाता है। मेरा लेख Type inference woes, part one है।

13

इस प्रयास करें:

int? result = condition ? 10 : default(int?);

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