2011-01-04 17 views
30

वे ढेर पर अपरिवर्तनीय मूल्य प्रकार हैं। मुझे उन्हें एक स्थिरता रखने से क्या बचाता है?क्यों structs को कॉन्स के रूप में घोषित नहीं किया जा सकता है?

संदर्भ:

+0

आप structs const घोषित कर सकते हैं। कक्षाएं और structs विनिमय करने योग्य हैं, और यह कक्षाओं के लिए काम करता है। – templatetypedef

+1

@templatetypedef: क्या मैं "शून्य से अलग" का उल्लेख करूंगा। – Lazlo

+0

@templatetypedef: मुझे यकीन नहीं है कि आप सी # का किस संस्करण का उपयोग कर रहे हैं, लेकिन यह मैंने देखा है कि किसी भी संस्करण पर यह सच नहीं है। – cdhowie

उत्तर

35

मान प्रकार निर्माता कुछ भी कर सकता क्योंकि - उदाहरण के लिए, स्विच तर्क दिन के समय के आधार पर । निरंतर मूल्य प्रकार बौद्धिक रूप से समझ में आता है, लेकिन यह रचनाकारों की लचीलापन के कारण जो भी वे कृपया करने के लिए अभ्यास में कस्टम मूल्य प्रकारों पर काम नहीं कर सकते हैं। (याद रखें कि स्थिरांक संकलन समय, जिसका अर्थ है अपने निर्माता संकलन समय पर चलाने के लिए होता है पर मूल्यांकन किया जाता है।)

+0

धन्यवाद, एस/ओ मुझे कब देता है स्वीकार करेगा। बहुत बुरा, अगर मैं कह सकता हूं, तो मेरे पास एक "कानूनी" कन्स्ट्रक्टर है, और मुझे यह सामना करना अच्छा लगेगा। लेकिन ओह ठीक है, मुझे लगता है कि मुझे लगता है कि एक और डिजाइन मिलेगा। – Lazlo

+2

@ लाज़लो: फिर भी, संकलक इसे संकलित करते समय इसे कॉल करना होगा। लेकिन संकलक तकनीकी रूप से आपके कोड को चलाने के लिए नहीं माना जाता है। – cdhowie

+2

मुझे लगता है कि मैं सी ++ के कुल या पीओडी structs के बराबर की तलाश में हूं: http://en.wikipedia.org/wiki/C%2B%2B_classes कुछ ऐसा जो कि एक अलग मूल्य प्रकार या डेटा का समूह है। ओह अच्छा। – Lazlo

18

सी # में कॉन्स्ट मतलब है कि यह संकलन समय पर निर्धारित किया जा सकता है, जिसके कारण बहुत ही आदिम int और string जैसे प्रकार एक कॉन्स हो सकते हैं।

यदि आप सी पृष्ठभूमि से आ रहे हैं, तो readonly कीवर्ड आपको बेहतर तरीके से अनुकूल कर सकता है।

+1

यह सी/सी ++ पृष्ठभूमि वाले प्रोग्रामर के लिए असली जवाब है। – Eonil

+1

@Eonil 100% नहीं; सी/सी ++ 'कॉन्स' कीवर्ड सी # के 'कॉन्स' और 'रीडोनली' दोनों के उद्देश्यों को पूरा करता है - उदाहरण के लिए, सी # में दो 'रीडोनली इंट' फ़ील्ड जोड़ना निरंतर फोल्डिंग नहीं होगा, जबकि दो 'कॉन्स int' चर जोड़ते हैं सी/सी ++ में (यदि मूल्य संकलन-समय पर ज्ञात हैं)। सी # की 'कॉन्स' सी ++ 11 'कॉन्टेक्सप्र' संशोधक के करीब है, जबकि सी # के 'रीडोनली' में सी/सी ++ में एकल एनालॉग नहीं है। – cdhowie

+0

@cdhowie, मुझे लगता है कि 'रीडोनली टी' के लिए एनालॉग है, जहां टी: स्ट्रक्चर ''टी टी' (सी ++ में) होगा। हालांकि, अधिकांश समय सी # में 'रीडोनली' कीवर्ड पर आता है, एक वास्तव में "कॉन्स शुद्धता" के लिए सी ++ का समर्थन ढूंढ रहा है जो सी # में मौजूद नहीं है (और अपरिवर्तनीय कक्षाओं/पैटर्न का नया सेट एक प्रदान करने की कोशिश करता है समान लेकिन काफी बेकार और श्रम-केंद्रित विकल्प)। – binki

4

मैं बस एक साधारण परिवर्तनशील struct साथ readonly कीवर्ड का परीक्षण किया:

struct Test 
{ 
    public int value; 

    public void setInt(int val) 
    { 
     value = val; 
    } 
} 

static class Program 
{ 
    public static readonly Test t = new Test(); 

    static void Main() 
    { 
     Console.WriteLine(t.value); // Outputs "0" 
     t.setInt(10); 
     //t.value = 10; //Illegal, will not let you assign field of a static struct 
     Console.WriteLine(t.value); // Still outputs "0" 
    } 
} 

हालांकि एक readonly struct एक संकलन समय निरंतर technicly नहीं है, क्रम अभ्यस्त इसे बदल दें। यहां तक ​​कि setInt() विधि को फेंकने के तरीके में यह मूल्य परिवर्तन की तरह दिखता है, लेकिन मुख्य में परिवर्तन नहीं दिखाता है।

मुझे लगता है कि संरचना स्वयं को "पठनीय" स्मृति में रखा गया है, जिससे उन्हें बदलने की अनुमति नहीं है। एक वर्ग के विपरीत, जो सूचक को स्थिर रखता है, जिससे कक्षा के क्षेत्र स्वयं को अपनी इच्छा के अनुसार बदल सकते हैं।

तो ऐसा लगता है कि static readonly प्रभावी रूप से const है, यहां तक ​​कि उत्परिवर्तनीय structs के लिए भी।

+4

संरचना के सभी उदाहरण विधियों, गुणों और घटनाओं को उस संरचना के संदर्भ में प्राप्त होता है जिस पर उन्हें संचालित करना चाहिए - '''' को' ref' पैरामीटर के रूप में प्राप्त करने के बराबर - लेकिन vb.net और C# में एक कष्टप्रद क्विर्क के लिए : यदि एक पठन-केवल संरचना उदाहरण पर एक स्ट्रक्चर विधि या प्रॉपर्टी लागू की जाती है, तो संकलक चुपचाप उस इंस्टेंस की एक प्रति बना देगा और कोड में प्रश्न को पास करेगा। यह उन मामलों में धीमी लेकिन सही अर्थशास्त्र पैदा करता है जहां कोड संरचना को संशोधित नहीं करता है, और उन मामलों में टूटा अर्थशास्त्र जहां कोड संरचना को संशोधित करता है। मेरी इच्छा है कि माइक्रोसॉफ्ट एक विशेषता परिभाषित करेगा ... – supercat

+3

... जो संरचना गुणों और विधियों को यह इंगित करने की अनुमति देगा कि वे पारित विधि को प्रभावित करते हैं या नहीं, ताकि संकलक उन विधियों को अनुमति दे सके जो 'इस' को उपयोग करने के लिए संशोधित नहीं करते हैं केवल पढ़ने के लिए structs पर लेकिन विधियों के उपयोग को मना कर दिया। अन्यथा, आपकी सबसे अच्छी शर्त कष्टप्रद और बदसूरत वाक्यविन्यास 'सार्वजनिक स्थैतिक शून्य सेटआईएनटी (रेफ टेस्ट, इंट वैल) {it.value = val;}' और 'Test.setInt (ref t, 10); जो सही ढंग से squawk होगा अगर आपने इसे केवल पढ़ने योग्य चर 't' पर करने की कोशिश की। – supercat

+0

@supercat, इसलिए हम वास्तव में चाहते हैं कि एमएस सी के 'const' के अर्थशास्त्र को सी # :- डी – binki

2

सी # कंपाइलर के लिए एक संरचना प्रकार के const मूल्य का उत्पादन करने के लिए यह पता होना चाहिए कि इसके सभी क्षेत्रों में मूल्यों को क्या जाना चाहिए। सी # कंपाइलर आंतरिक रूप से जानता है कि Decimal जैसे कुछ प्रकार के क्षेत्रों को कैसे प्रारंभ किया जाए, लेकिन अधिकांश मूल्य प्रकारों के लिए इसका कोई ज्ञान नहीं है।

एक कंपाइलर के लिए संदर्भों में संरचना प्रकार के निरंतर मूल्यों को घोषित करने का साधन प्रदान करना संभव होगा जहां struct फ़ील्ड का खुलासा किया गया था। यदि संरचना का क्षेत्र private था, तो उस प्रकार के स्थिरांक को केवल संरचना के भीतर घोषित किया जा सकता था; यदि फ़ील्ड internal थे, तो असेंबली के भीतर कहीं भी स्थिरांक घोषित किया जा सकता था; यदि public, उन्हें कहीं भी घोषित किया जा सकता है।

हालांकि मैं ऐसी सुविधा देखना चाहता हूं, मुझे किसी भी मुख्यधारा के .NET भाषाओं को लागू करने की उम्मीद नहीं है। कंपाइलर के स्वाभाविक रूप से जानता है कि प्रकार के स्थिरांक अन्य निरंतर अभिव्यक्तियों में भाग ले सकते हैं, जबकि static readonly चर नहीं कर सकते हैं। यदि NumRows 4 के बराबर स्थिर है, तो Arr[3*NumRows+7] जैसी अभिव्यक्ति को Arr[19] द्वारा प्रतिस्थापित किया जा सकता है भले ही NumRows किसी बाहरी असेंबली में परिभाषित किया गया हो।यह ऐसे स्थिरांक को static readonly चर से अधिक लाभ प्रदान करता है। यदि, हालांकि, स्थिरता एक प्रकार का है जो एक कंपाइलर आंतरिक रूप से पहचान नहीं लेता है, तो किसी भी निरंतर अभिव्यक्ति में भाग लेने की बहुत सीमित क्षमता होगी, जो पहले स्थान पर स्थिर होने के लाभ को प्रभावी ढंग से अस्वीकार कर देगी। यदि एक मूल्य-प्रकार निरंतर एक खुला क्षेत्र था, तो एक कंपाइलर के लिए निरंतर के रूप में उस क्षेत्र के मूल्य का उपयोग करना संभव होगा, लेकिन चूंकि .NET भाषाओं के निर्माता दार्शनिक रूप से खुला क्षेत्रों के साथ संरचनाओं का विरोध कर रहे हैं, तो मुझे उम्मीद नहीं होगी उन्हें इस तरह के उपयोग की इजाजत देने के लिए भी अगर वे कर सकते हैं।

static readonly चर से अधिक स्थिरांक के पक्ष में कुछ संभावित उपयोग मामले होंगे, लेकिन ऐसे कई मामलों को मौजूदा प्रकारों का उपयोग करके स्वीकार्य रूप से संभाला जा सकता है। उदाहरण के लिए, एक लाइब्रेरी const Int64 को अपने संस्करण के बारे में जानकारी एन्कोड करने के लिए उजागर कर सकती है, और उस मान का उपयोग GetLinkedVersionInfo विधि के लिए डिफ़ॉल्ट पैरामीटर मान के रूप में करें। प्रश्न में मूल्य कॉलिंग कोड को "बेक किया गया" जब संकलित किया गया था, इस प्रकार विधि को यह रिपोर्ट करने की इजाजत दी गई कि लाइब्रेरी के किस संस्करण के साथ कॉलर लिंक किया गया था, और संभावित रूप से यह पहचानने की अनुमति है कि संस्करण के साथ कोई संगतता समस्या है या नहीं।

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

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