2012-04-17 17 views
5

असल में सी # में निम्नलिखित क्यों अमान्य है? मुझे इसके लिए बहुत अच्छे उपयोग मिल सकते हैं और वास्तव में इसे अपनी खुद की नामुमकिन संरचना वर्ग बनाकर ठीक कर सकते हैं, लेकिन सी # विनिर्देश (और इसलिए संकलक) क्यों और कैसे रोकता है?'संरचना Nullable <T>' संरचना क्यों नहीं है?

नीचे जो मैं बात कर रहा हूं उसका आंशिक उदाहरण नीचे दिया गया है।

struct MyNullable<T> where T : struct 
{ 
    public T Value; 
    public bool HasValue; 

    // Need to overide equals, as well as provide static implicit/explit cast operators 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Compiles fine and works as expected 
     MyNullable<Double> NullableDoubleTest; 
     NullableDoubleTest.Value = 63.0; 

     // Also compiles fine and works as expected 
     MyNullable<MyNullable<Double>> NullableNullableTest; 
     NullableNullableTest.Value.Value = 63.0; 

     // Fails to compile...despite Nullable being a struct 
     // Error: The type 'double?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'ConsoleApplication1.MyNullable<T>' 
     MyNullable<Nullable<Double>> MyNullableSuperStruct; 
    } 
} 
+1

क्या आप पूछ रहे हैं कि आप एक निरर्थक शून्य क्यों नहीं बना सकते? शायद अगर आपने केवल कोड के बजाय * शब्दों * में प्रश्न का phrasing करने का प्रयास किया है, तो आप समझ जाएंगे कि यह अधिक समझ में क्यों नहीं आता है। –

+0

@ एलबी यह एक सूचक के लिए सूचक के लिए एक सूचक के समान है। डबल पॉइंटर शून्य हो सकता है, पॉइंटर शून्य हो सकता है, या वे दोनों एक घाटी हो सकते हैं। संपादित करें: बेशक इसकी अनुमति नहीं है, इसलिए यह एक महत्वपूर्ण मुद्दा है। – Servy

+0

मैंने आपके कोड को संकलित करने की कोशिश की (LINQPad में) और मुझे _ प्रकार 'int' मिलता है? ** जेनेरिक प्रकार या विधि 'UserQuery.MyNullable ' _ में पैरामीटर 'टी' के रूप में इसका उपयोग करने के लिए ** एक गैर-शून्य मूल्य मान ** होना चाहिए। क्या आप इसे संकलित करने का प्रयास करते समय अलग हैं? –

उत्तर

8

यह struct है। यह सिर्फ मान प्रकार जेनेरिक प्रकार पैरामीटर बाधा को संतुष्ट नहीं करता है। 10.1.5 भाषा विनिर्देशन से:

मान प्रकार की बाधा निर्दिष्ट करती है कि प्रकार पैरामीटर के लिए उपयोग किए जाने वाले एक प्रकार का तर्क एक गैर-शून्य मूल्य मान होना चाहिए। सभी गैर-नामुमकिन संरचना प्रकार, enum प्रकार, और मान पैरामीटर वाले प्रकार पैरामीटर इस बाधा को पूरा करते हैं। ध्यान दें कि हालांकि मान प्रकार के रूप में वर्गीकृत, एक शून्य प्रकार (§4.1.10) मान प्रकार की बाधा को पूरा नहीं करता है।

तो, where T : struct का मतलब यह नहीं है कि इसका क्या अर्थ है।

असल में सी # में निम्नलिखित क्यों अमान्य है?

क्योंकि where T : struct केवल T से संतुष्ट हो सकता है जो गैर-शून्य मूल्य प्रकार हैं। Nullable<TNonNullableValueType> इस बाधा को पूरा नहीं करता है।

संकलक इसे क्यों और कैसे रोकता है?

क्यों? विनिर्देश के साथ संगत होने के लिए। कैसे? वाक्य रचनात्मक और अर्थपूर्ण विश्लेषण करके और यह निर्धारित करना कि आपने एक सामान्य प्रकार पैरामीटर T प्रदान किया है जो सामान्य प्रकार की बाधा where T : struct को संतुष्ट नहीं करता है।

[मैं] यह मेरे अपने नल struct वर्ग बनाने के द्वारा ठीक कर सकते हैं लेकिन

नहीं, आप संस्करण यह दुरुस्त नहीं होता हो। यह मूल रूप से Nullable<T> जैसा ही है, सिवाय इसके कि आपको कंपाइलर द्वारा विशेष हैंडलिंग नहीं मिलती है, और आप कुछ मुक्केबाजी का कारण बनेंगे कि कंपाइलर का कार्यान्वयन बॉक्स नहीं होगा।

मैं के लिए यह

सच अच्छा उपयोग करता है के बहुत सारे मिल सकते हैं? जैसे कि? ध्यान रखें, Nullable<T> का मूल विचार एक संग्रहण स्थान है जिसमें T हो सकता है या "मान गुम है" का प्रतिनिधित्व कर सकता है। यह घोंसला करने का मुद्दा क्या है? यही है, Nullable<Nullable<T>> का बिंदु क्या है? यह वैचारिक भावना भी नहीं बनाता है। यही कारण है कि यह निषिद्ध है, लेकिन मैं केवल अनुमान लगा रहा हूं (एरिक लिपर्ट के पास confirmed है कि यह अनुमान सही है)। उदाहरण के लिए, int?? क्या है? यह एक भंडारण स्थान का प्रतिनिधित्व करता है जो मानता है कि मान गुम है या int? है, जो स्वयं एक भंडारण स्थान है जो मानता है कि मान गुम है या int है? क्या फायदा?

+0

मुझे लगता है कि ओपी का असली सवाल है "क्यों 10.1.5 में शामिल है 'ध्यान दें कि हालांकि मान प्रकार के रूप में वर्गीकृत किया गया है, एक शून्य प्रकार (§4.1.10) मान प्रकार की बाधा को पूरा नहीं करता है।" – Gabe

+0

@Gabe मैं भी इससे सहमत नहीं हूं। जेसन का जवाब सही है। 10.1.5 ओपी को बताता है कि उसका कोड क्यों काम नहीं करता है। –

+0

@AndrewFinnell यह निर्भर करता है कि ओपी भाषा डिजाइन के पीछे कारण जानने का प्रयास कर रहा है या नहीं। "मेरे कोड का काम क्यों नहीं करता" के बारे में प्रश्नों का उत्तर दिया जा सकता है "क्योंकि भाषा इस तरह डिज़ाइन की गई थी"; "इस तरह की भाषा क्यों बनाई गई थी" के बारे में प्रश्न नहीं कर सकते हैं। – phoog

2

संरचना बाधाओं के निचले स्तरों को हटाने का एक कारण यह है कि हम सामान्य तरीकों से T? का उपयोग करने में सक्षम होना चाहते हैं। यदि struct ने अनुपलब्ध मान प्रकारों की अनुमति दी है, तो संकलक को T? को प्रतिबंधित करना होगा।

नल प्रकार अन्य मामलों में संकलक में विशेष हैंडलिंग के साथ-साथ होना चाहिए:

  • अशक्त कीवर्ड परोक्ष एक नल प्रकार के लिए परिवर्तनीय होना चाहिए; यह एक मूल्य प्रकार के साथ असंभव है।
  • शून्य मूल्य वाले कीवर्ड के साथ शून्य मूल्यों की तुलना की जा सकती है; गैर-शून्य मूल्य प्रकारों के साथ, यह तुलना हमेशा झूठी होती है।
  • शून्य मूल्य प्रकार ?? ऑपरेटर के साथ काम करते हैं; गैर-शून्य नहीं है।
+0

यदि Nullable की टी प्रकार तर्क बाधा वास्तव में संरचना और Nullable वास्तव में संरचना से व्युत्पन्न था तो टी? जो भी टी था, उसके आस-पास एक न्यूलबल लपेटेगा। तो Nullable Nullable होगा > – NtscCobalt

+0

@NtscCobalt: और 'Nullable >' एक बेकार अवधारणा है। – jason

+0

@Jason, शायद लेकिन टी एक struct हो की आवश्यकता होती है एक प्रकार तर्क के लिए Nullable का उपयोग कर भावना के रूप में Nullable के रूप में परिभाषित किया गया है बनाता है struct Nullable : जहां टी struct {टी मूल्य; बूल HasValue;} तो तर्कसंगत रूप से यह भ्रमित हो सकता है लेकिन संकलक को रोकने के लिए कोई कारण नहीं होना चाहिए (विनिर्देश के अलावा)। – NtscCobalt

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