2008-09-20 8 views
65

एक बार फिर उनमें से एक: "क्या मेरे सहायक तरीके की बजाय चीजों को करने का एक आसान तरीका है?"मैं एक सिस्टम को कैसे परिवर्तित करूं? इसके निरर्थक संस्करण में टाइप करें?

तो अंतर्निहित प्रकार को एक शून्य प्रकार से प्राप्त करना आसान है, लेकिन मैं .NET प्रकार का संक्षिप्त संस्करण कैसे प्राप्त करूं?

तो मैं

typeof(int) 
typeof(DateTime) 
System.Type t = something; 

है और मैं

int? 
DateTime? 

या

Nullable<int> (which is the same) 
if (t is primitive) then Nullable<T> else just T 

वहाँ एक अंतर्निहित विधि है करना चाहते हैं?

उत्तर

91

यहाँ कोड मैं का उपयोग करें:

Type GetNullableType(Type type) { 
    // Use Nullable.GetUnderlyingType() to remove the Nullable<T> wrapper if type is already nullable. 
    type = Nullable.GetUnderlyingType(type); 
    if (type.IsValueType) 
     return typeof(Nullable<>).MakeGenericType(type); 
    else 
     return type; 
} 
+0

अच्छा! यह वास्तव में एक साफ समाधान है। – ljs

+0

महान जवाब! मुझे इसकी ही खोज थी। –

+0

कूल समाधान। इसे स्वयं टाइप पर एक विस्तार विधि बनाने के बारे में क्या? इस स्थिति में उपयुक्त लगता है। –

2

उस में बनाया मैं के बारे में पता कुछ भी, int?, आदि के रूप में नहीं है Nullable<T> के लिए बस वाक्यात्मक चीनी है, और उससे परे विशेष उपचार नहीं दिया जाता है। यह विशेष रूप से असंभव है क्योंकि आप इसे किसी दिए गए प्रकार की प्रकार की जानकारी से प्राप्त करने का प्रयास कर रहे हैं। आम तौर पर हमेशा दिए गए कुछ के रूप में कुछ 'अपना खुद का रोल' कोड जरूरी है। आपको इनपुट प्रकार के प्रकार पैरामीटर के साथ एक नया Nullable प्रकार बनाने के लिए प्रतिबिंब का उपयोग करना होगा।

संपादित करें: टिप्पणी के रूप में वास्तव में सुझाव है Nullable<> विशेष रूप से इलाज किया है, और क्रम के रूप में this article में विस्तार से बताया बूट करने में।

+0

Actaully भी निश्चित होती है, मैं बहुत यकीन है कि CLR Nullable से निपटने <> की कुछ अलग तरह के लिए कुछ विशेष जादू है हूँ। मुझे यह जांचना होगा। – TraumaPony

+0

मुझे इसमें दिलचस्पी होगी, यह स्वीकार करने में प्रसन्नता हो कि मैं गलत हूं यदि यह मामला है :-) – ljs

+0

सीएलआर के पास नलबेल के लिए विशेष हैंडलिंग है। http://blogs.msdn.com/somasegar/archive/2005/08/11/450640.aspx –

7

लाइमैन का जवाब बहुत अच्छा है और मेरी मदद की है, हालांकि, एक और बग है जिसे ठीक करने की आवश्यकता है।

Nullable.GetUnderlyingType(type) केवल तभी कहा जाना चाहिए यदि प्रकार पहले से Nullable प्रकार नहीं है। अन्यथा, जब System.RuntimeType से प्राप्त होता है (जैसे कि जब मैं typeof(System.Int32) में जाता हूं) तो यह गलती से शून्य हो जाता है। नीचे दिए गए संस्करण को Nullable.GetUnderlyingType(type) पर कॉल करने की आवश्यकता है, यह जांचकर कि Nullable है या नहीं। जब तक यह एक ValueType कि पहले से ही Nullable नहीं है

आप नीचे इस विधि है जो तुरंत प्रकार वापस आ जाएगी का एक ExtensionMethod संस्करण मिल जाएगा।

Type NullableVersion(this Type sourceType) 
{ 
    if(sourceType == null) 
    { 
     // Throw System.ArgumentNullException or return null, your preference 
    } 
    else if(sourceType == typeof(void)) 
    { // Special Handling - known cases where Exceptions would be thrown 
     return null; // There is no Nullable version of void 
    } 

    return !sourceType.IsValueType 
      || (sourceType.IsGenericType 
       && sourceType.GetGenericTypeDefinition() == typeof(Nullable<>)) 
     ? sourceType 
     : typeof(Nullable<>).MakeGenericType(sourceType); 
} 

(मैं माफी चाहता हूँ, लेकिन मैं बस लीमन के जवाब के लिए एक टिप्पणी पोस्ट नहीं कर सके क्योंकि मैं नया था और अभी तक पर्याप्त प्रतिनिधि नहीं था।)

14

मैं तरीकों में से एक जोड़ी मैं मैंने अपनी उपयोगिता पुस्तकालय में लिखा है कि मैंने बहुत भरोसा किया है।

/// <summary> 
    /// [ <c>public static Type GetNullableType(Type TypeToConvert)</c> ] 
    /// <para></para> 
    /// Convert any Type to its Nullable&lt;T&gt; form, if possible 
    /// </summary> 
    /// <param name="TypeToConvert">The Type to convert</param> 
    /// <returns> 
    /// The Nullable&lt;T&gt; converted from the original type, the original type if it was already nullable, or null 
    /// if either <paramref name="TypeToConvert"/> could not be converted or if it was null. 
    /// </returns> 
    /// <remarks> 
    /// To qualify to be converted to a nullable form, <paramref name="TypeToConvert"/> must contain a non-nullable value 
    /// type other than System.Void. Otherwise, this method will return a null. 
    /// </remarks> 
    /// <seealso cref="Nullable&lt;T&gt;"/> 
    public static Type GetNullableType(Type TypeToConvert) 
    { 
     // Abort if no type supplied 
     if (TypeToConvert == null) 
      return null; 

     // If the given type is already nullable, just return it 
     if (IsTypeNullable(TypeToConvert)) 
      return TypeToConvert; 

     // If the type is a ValueType and is not System.Void, convert it to a Nullable<Type> 
     if (TypeToConvert.IsValueType && TypeToConvert != typeof(void)) 
      return typeof(Nullable<>).MakeGenericType(TypeToConvert); 

     // Done - no conversion 
     return null; 
    } 

दूसरी विधि बस की रिपोर्ट हैं कि कोई प्रकार नल है: पहले एक विधि है कि इसके लिए इसी Nullable < प्रकार > विधि में कोई भी प्रकार परिवर्तित करता है।इस विधि पहले से कहा जाता है और अलग से उपयोगी है:

/// <summary> 
    /// [ <c>public static bool IsTypeNullable(Type TypeToTest)</c> ] 
    /// <para></para> 
    /// Reports whether a given Type is nullable (Nullable&lt; Type &gt;) 
    /// </summary> 
    /// <param name="TypeToTest">The Type to test</param> 
    /// <returns> 
    /// true = The given Type is a Nullable&lt; Type &gt;; false = The type is not nullable, or <paramref name="TypeToTest"/> 
    /// is null. 
    /// </returns> 
    /// <remarks> 
    /// This method tests <paramref name="TypeToTest"/> and reports whether it is nullable (i.e. whether it is either a 
    /// reference type or a form of the generic Nullable&lt; T &gt; type). 
    /// </remarks> 
    /// <seealso cref="GetNullableType"/> 
    public static bool IsTypeNullable(Type TypeToTest) 
    { 
     // Abort if no type supplied 
     if (TypeToTest == null) 
      return false; 

     // If this is not a value type, it is a reference type, so it is automatically nullable 
     // (NOTE: All forms of Nullable<T> are value types) 
     if (!TypeToTest.IsValueType) 
      return true; 

     // Report whether TypeToTest is a form of the Nullable<> type 
     return TypeToTest.IsGenericType && TypeToTest.GetGenericTypeDefinition() == typeof(Nullable<>); 
    } 

IsTypeNullable उपरोक्त क्रियान्वयन एक विजेता हर बार की तरह काम करता है, लेकिन यह थोड़ा वर्बोज़ और अपने पिछले कोड लाइन में धीमी है।

 // Abort if no type supplied 
     if (TypeToTest == null) 
      return false; 

     // If this is not a value type, it is a reference type, so it is automatically nullable 
     // (NOTE: All forms of Nullable<T> are value types) 
     if (!TypeToTest.IsValueType) 
      return true; 

     // Report whether an underlying Type exists (if it does, TypeToTest is a nullable Type) 
     return Nullable.GetUnderlyingType(TypeToTest) != null; 

आनंद लें: को छोड़कर पिछले कोड लाइन में आसान है और तेजी से निम्न कोड शरीर, IsTypeNullable के लिए ऊपर के रूप में ही है!

मार्क

पीएस - "शून्यता" के बारे में

मुझे एक अलग पोस्ट में बनाई गई शून्यता के बारे में एक बयान दोहराया जाना चाहिए, जो सीधे इस विषय को सही ढंग से संबोधित करने के लिए लागू होता है। यही है, मेरा मानना ​​है कि यहां चर्चा का ध्यान यह नहीं होना चाहिए कि यह देखने के लिए कि कोई ऑब्जेक्ट सामान्य जेनेबल प्रकार है या नहीं, बल्कि कोई भी इसके प्रकार के किसी ऑब्जेक्ट को शून्य का मान निर्दिष्ट कर सकता है या नहीं। दूसरे शब्दों में, मुझे लगता है कि हमें यह निर्धारित करना चाहिए कि ऑब्जेक्ट प्रकार शून्य है, न कि यह शून्य है। अंतर अर्थशास्त्र में है, अर्थात् शून्यता निर्धारित करने के लिए व्यावहारिक कारण, जो आमतौर पर महत्वपूर्ण है।

रन-टाइम (वेब ​​सेवाएं, रिमोट कॉल, डेटाबेस, फ़ीड्स इत्यादि) तक संभवतः अज्ञात प्रकारों वाले ऑब्जेक्ट्स का उपयोग करने वाली प्रणाली में, एक सामान्य आवश्यकता यह निर्धारित करना है कि ऑब्जेक्ट को शून्य को असाइन किया जा सकता है या नहीं वस्तु में एक शून्य हो सकती है। गैर-निरर्थक प्रकारों पर ऐसे परिचालन करने से संभवतः त्रुटियां उत्पन्न होती हैं, आमतौर पर अपवाद, जो प्रदर्शन और कोडिंग आवश्यकताओं के संदर्भ में बहुत महंगा होते हैं। ऐसी समस्याओं से बचने के अत्यधिक पसंदीदा दृष्टिकोण को लेने के लिए, यह निर्धारित करना आवश्यक है कि मनमानी प्रकार का एक वस्तु शून्य न हो; यानी, चाहे वह आम तौर पर 'शून्य' हो।

एक बहुत ही व्यावहारिक और सामान्य अर्थ में, .NET शर्तों में शून्यता बिल्कुल जरूरी नहीं है कि किसी ऑब्जेक्ट का प्रकार शून्य के रूप में है। वास्तव में कई मामलों में, वस्तुओं के संदर्भ प्रकार होते हैं, इसमें शून्य मूल्य हो सकता है, और इस प्रकार सभी शून्य हो सकते हैं; इनमें से कोई भी एक शून्य प्रकार नहीं है। इसलिए, अधिकांश परिदृश्यों में व्यावहारिक उद्देश्यों के लिए, शून्यता की कार्यान्वयन-निर्भर अवधारणा बनाम, शून्यता की सामान्य अवधारणा के लिए परीक्षण किया जाना चाहिए। तो हमें पूरी तरह से .NET Nullable प्रकार पर ध्यान केंद्रित करके लटका नहीं जाना चाहिए बल्कि शून्य, सामान्यता की सामान्य, व्यावहारिक अवधारणा पर ध्यान केंद्रित करने की प्रक्रिया में इसकी आवश्यकताओं और व्यवहार की हमारी समझ को शामिल करना चाहिए।

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

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