2008-11-17 17 views
134

कोई समझा सकते हैं क्यों इस में काम करता है सी # .NET 2.0:Nullable प्रकार मुद्दा: सशर्त ऑपरेटर

Nullable<DateTime> foo; 
    if (true) 
     foo = null; 
    else 
     foo = new DateTime(0); 

... लेकिन यह नहीं करता है:

Nullable<DateTime> foo; 
    foo = true ? null : new DateTime(0); 

बाद वाले मिलकर देता है मुझे एक संकलन त्रुटि "सशर्त अभिव्यक्ति का प्रकार निर्धारित नहीं किया जा सकता है क्योंकि '< शून्य >' और 'System.DateTime' के बीच कोई अंतर्निहित रूपांतरण नहीं है।"

नहीं कि मैं पूर्व का उपयोग नहीं कर सकता, लेकिन दूसरी शैली मेरे शेष कोड के साथ अधिक सुसंगत है।

+11

आप डेटटाइम का उपयोग कर अपने आप को बहुत से टाइपिंग से बचा सकते हैं? Nullable के बजाय। –

उत्तर

282

इस प्रश्न को पहले से ही कई बार पूछा गया है। कंपाइलर आपको बता रहा है कि यह नहीं जानता कि null को DateTime में कैसे परिवर्तित करें।

समाधान सरल है:

DateTime? foo; 
foo = true ? (DateTime?)null : new DateTime(0); 

ध्यान दें कि Nullable<DateTime>DateTime? जो आप टाइप के एक झुंड की बचत होगी लिखा जा सकता है।

+0

अच्छी तरह से काम करता है लेकिन अब आप फू को चेक नहीं कर सकते - यह हमेशा एक मूल्य होगा। हालांकि इसके आसपास कोई रास्ता नहीं - जैसा कि मोजोफिल्टर कहते हैं, "ऐसा इसलिए है क्योंकि एक टर्नरी ऑपरेटर में, दो मान एक ही प्रकार के होने चाहिए।" – DilbertDave

+0

@DilbertDave MojoFilter की पोस्ट से जानकारी गलत है। – Mishax

+3

मैं जोड़ता हूं कि कंपाइलर परिणामी प्रकार के टर्नरी ऑपरेशन को अनुमान लगाने की कोशिश करता है न कि वेरिएबल को देखकर, लेकिन इसके बजाए ऑपरेटरों को देखकर। यह ' 'और' डेटटाइम 'और सामान्य पूर्वजों के प्रकार को खोजने के बजाय, यह सिर्फ एक दूसरे के बीच एक रूपांतरण खोजने की कोशिश करता है। (अतिरिक्त बिट: सी # एक '' प्रकार, यानी प्रत्येक 'शून्य' अभिव्यक्ति का प्रकार पहचानता है।) – IllidanS4

7

ऐसा इसलिए है क्योंकि एक टर्नरी ऑपरेटर में, दो मानों को एक ही प्रकार के लिए हल करना होगा।

+7

नहीं, उन्हें एक ही प्रकार का होना जरूरी नहीं है। या तो दूसरा ऑपरेंड तीसरे ऑपरेंड के प्रकार या दूसरी तरफ के रूप में पूरी तरह से परिवर्तनीय होना चाहिए। – Mishax

16

FYI करें (Offtopic, लेकिन निफ्टी और नल प्रकार से संबंधित) हम नल प्रकार बस के लिए अशक्त कोलेसिंग ऑपरेटर

?? 

इस तरह प्रयुक्त नाम की एक आसान ऑपरेटर है:

// Left hand is the nullable type, righthand is default if the type is null. 
Nullable<DateTime> foo; 
DateTime value = foo ?? new DateTime(0); 
+6

यह उनके प्रश्न का उत्तर कैसे देता है ?? –

+1

निक कुछ शर्त सही होने पर फू को शून्य करने की कोशिश कर रहा है। नल coalesce foo शून्य है अगर मूल्य के लिए दिनांक समय (0) असाइन करेगा। दोनों पूरी तरह से असंबंधित हैं। –

+2

इसलिए एफवाईआई, ऑफटॉपिक लेकिन जानना एक अच्छी बात है। – FlySwat

6

एक अन्य समाधान स्वीकार्य के समान सी # के default कीवर्ड का उपयोग करना है। जेनेरिक का उपयोग करके परिभाषित करते समय, यह वास्तव में किसी भी प्रकार के लिए लागू होता है।

उदाहरण उपयोग ओपी के सवाल करने के लिए लागू: वर्तमान स्वीकृत जवाब के साथ

Nullable<DateTime> foo; 
foo = true ? default(DateTime) : new DateTime(0); 

उदाहरण उपयोग: default का उपयोग करके

DateTime? foo; 
foo = true ? default(DateTime) : new DateTime(0); 

इसके अलावा, आप nullable के रूप में चर निर्दिष्ट करने की आवश्यकता नहीं है इसे null मान असाइन करने के लिए। कंपाइलर विशिष्ट चर-प्रकार के डिफ़ॉल्ट मान को स्वत: असाइन करेगा और कोई त्रुटि नहीं आएगी। उदाहरण:

DateTime foo; 
foo = true ? default(DateTime) : new DateTime(0); 
+0

कूल, यह जानने में आसान है –

+8

सच नहीं है, 'डिफ़ॉल्ट (डेटटाइम) 'शून्य नहीं है, यह' 1.1.0001 0: 00: 00' "है, जो' नया दिनांक समय (0)' जैसा है। – IllidanS4

3

मुझे पता है कि 2008 में यह प्रश्न पूछा गया था और अब यह 5 साल बाद है लेकिन उत्तर के रूप में चिह्नित उत्तर मुझे संतुष्ट नहीं करता है। असली जवाब यह है कि डेटटाइम एक संरचना है, और एक संरचना के रूप में यह शून्य के साथ संगत नहीं है। आपके पास हल करने के दो तरीके हैं:

सबसे पहले डेटटाइम के साथ शून्य संगत बनाना है (उदाहरण के लिए, डेटटाइम पर कास्ट नल? 70 अपवॉट्स के साथ सज्जन के रूप में, या ऑब्जेक्ट या वैल्यू टाइप में नल डालें)।

दूसरा डेटटाइम को शून्य के साथ संगत बनाना है (उदाहरण के लिए, डेटटाइम डेटटाइम को डेटटाइम?)।

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