2012-04-25 13 views
5

मैं एक सामान्य कनवर्टरसामान्य विधि

यहाँ बनाने हूँ में नल के लिए परिवर्तन नहीं कर सकते जेनेरिक कनवर्टर

bool TryReaderParse<TType>(object data, out TType value) 
{ 
    value = default(TType); 
    Type returnType = typeof(TType); 
    object tmpValue = null; 

    if (returnType == typeof(DateTime)) 
    { 
     tmpValue = StringToDatetime(data.ToString()); 
    } 
    else if (returnType == typeof(DateTime?)) // THIS IF FIRES 
    { 
     tmpValue = StringToNullableDatetime(data.ToString()); 
    } 

    value = (TType)Convert.ChangeType(tmpValue, returnType); // THROWS 
} 

public DateTime? StringToNullableDatetime(string date) 
{ 
    DateTime? datetime = null; 
    if (!string.IsNullOrEmpty(date)) 
    { 
     datetime = DateTime.Parse(date, new CultureInfo(Resources.CurrentCulture)); 
    } 

    return datetime; 
} 

का एक नमूना कोड है और यह है मैं इसे कैसे उपयोग करें:

void foo() 
{ 
    DateTime? date = null; 
    TryReaderParse<DateTime?>("25/12/2012", out date); 
} 

फेंक दिया अपवाद कहता है कि यह DateTime से Nullable<DateTime> में परिवर्तित नहीं हो सकता है। चूंकि, विधि एक नामुमकिन प्रकार बनाता है और लौटाता है, कास्टिंग कैसे विफल हो जाता है?

अंत में, मैं इस विशेष उदाहरण में एक निरर्थक डेटटाइम रखना चाहता हूं।

संपादित समस्या यह है कि StringToNullableDatetime विधि एक Datetime? वापस आती है और कास्टिंग का कहना है कि से Datetime

परिवर्तित नहीं कर सकते जब से StringToNullableDatetime विधि एक नल दिनांक देता है, यह कैसे संभव है कि Convert.ChangeType कि पारित नहीं देख सकते हैं तर्क शून्य है?

Ps। मैंने this जैसे उत्तरों को पढ़ा है जो विपरीत (नाली योग्य से कास्टिंग) करते हैं।

मान शून्य है और रूपांतरण प्रकार एक मान प्रकार

Nullable<T> एक struct और इसलिए एक मान प्रकार है, इस प्रकार आप नहीं कर सकते:

उत्तर

18

फेंक दिया अपवाद कहता है कि यह DateTime से Nullable<DateTime> में परिवर्तित नहीं हो सकता है। चूंकि, विधि एक नामुमकिन प्रकार बनाता है और लौटाता है, कास्टिंग कैसे विफल हो जाता है?

अच्छा सवाल। यह विफल रहता है क्योंकि कोई बॉक्सिंग नलबल जैसी कोई चीज़ नहीं है। जब आप DateTime? से object को कनवर्ट करते हैं, तो आपको DateTime? शून्य था, या तो मान, DateTime पर आपको एक शून्य संदर्भ मिलता है। आपको कभी भी बक्सेदार नालीदार संरचना नहीं मिलती है; ऐसा कुछ नहीं है।

इसलिए आप उस बॉक्स में या तो शून्य या वैध डेटटाइम के साथ समाप्त होते हैं। फिर आप कन्वर्ट को उस निरर्थक डेटटाइम में कनवर्ट करने के लिए कहें, और कन्वर्ट नहीं जानता कि यह कैसे करें।

मेरी सलाह यह है कि आप पूरी तरह से हमले की इस पंक्ति को छोड़ दें; यह कोड जेनेरिक के अपमानजनक सीमा रेखा है। जब भी आप सामान्य प्रकार के सामान्य प्रकार पर स्विच करते हैं, तो आपका कोड अब जेनेरिक नहीं है और आप शायद इसे गलत कर रहे हैं। आप तो datetimes के लिए एक "कोशिश" शैली विधि करने के लिए चाहते हैं, तो सिर्फ इतना है कि लिखें:

DateTime? TryReadDateTime(object data) 
{ 
    ... return null if the object cannot be read as a datetime ... 
} 

हर प्रकार है कि आप पढ़ सकते हैं करना चाहते हैं के लिए इस तरह के एक विधि लिखें। उपयोगकर्ता ज्यादा नहीं बल्कि लिखना होगा:

DateTime? d = TryReadDateTime(data); 
if (d != null) ... 

से

DateTime d; 
bool b = TryRead<DateTime>(data, out d); 
if (b) ... 
0
documentation से

, इस लाइन यदि त्रुटि होगा यदि आपका मान शून्य है तो इस विधि कॉल का उपयोग करें। आप पहले से ही तारीखों को अलग से संभालते हैं, तो फिर भी उन मामलों में ChangeType का उपयोग क्यों करें?

+0

मेरे सवाल का संपादन किया। मेरी समस्या यह है कि मैं एक नामुमकिन डेटाटाइम वापस नहीं कर सकता। 'कनवर्ट। चेंज टाइप' लाइन नहीं देख सकती है कि उत्तीर्ण तर्क शून्य है – Odys

0

जिस तरह से शून्य, जेनेरिक, और मुक्केबाजी इंटरैक्ट अजीब है। आप से बेहतर दो तरीकों को परिभाषित किया जा सकता है:

 
bool TryReaderParse(object data, out TType value); 
bool TryReaderParse(object data, out TType? value) where TType : struct; 

दूसरी विधि के भीतर, अपने कोड बस एक TType उत्पादन और TType? करने के लिए इसे बिना किसी कठिनाई के असाइन कर सकते हैं।

+2

सबसे पहले, एक विधि अकेले बाधाओं पर अधिभारित नहीं हो सकती है। दूसरा, यदि विधि एक शून्य मूल्य प्रदान करती है तो * उसे बूल * वापस करने की आवश्यकता क्यों होती है? यदि आप ऐसा करने जा रहे हैं तो सही हस्ताक्षर 'टी TryParseClass (ऑब्जेक्ट डेटा) हैं जहां टी: कक्षा' और' टी? TryParseStruct (ऑब्जेक्ट डेटा) जहां टी: struct'। कोई बूल आवश्यक नहीं है। –

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