2012-08-15 19 views
28

मैं एक मूल्य के लिए एक "स्थिरांक" पहले से स्पष्ट रूप से मेरी कोड में कई बार कहा गया है बनाया:यह संकलन क्यों करेगा?

private static readonly int QUARTER_HOUR_COUNT = 96; 

जब मैं एक QUARTER_HOUR_COUNT के लिए 96 की खोज एवं प्रतिस्थापन किया था, मैं अनजाने भी घोषणा की जगह, तो यह बन गया:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

... अभी तक यह संकलित है। मुझे लगता है कि यह उसको अस्वीकार कर देगा। इसे वैध घोषणा के रूप में संकलक द्वारा क्यों स्वीकार किया गया था?

+0

QUARTER_HOUR_COUNT को क्योंकि यह स्थिर है असाइन किया गया है! – canon

+0

वाह! यह निश्चित रूप से आश्चर्यजनक व्यवहार है। – leppie

+0

क्योंकि गलत करने के लिए असीमित तरीके हैं। – Jodrell

उत्तर

23

I would think that it would disallow that. Why was it accepted by the compiler as a valid declaration?

संभवतः भाषा विनिर्देश इसकी अनुमति देता है। क्या आपके पास भाषा विनिर्देश में एक विशिष्ट नियम है जो आपको लगता है कि इसे प्रतिबंधित करता है?

अपने प्रश्न वास्तव में है "क्यों भाषा विनिर्देश इस निषेध नहीं करता है" - मुझे लगता है क्योंकि यह शायद वाकई केवल चीजें आप वास्तव में प्रतिबंधित करने के लिए चाहते हैं निषेध बनाने के लिए काफी मुश्किल है यह है, जबकि वास्तव में इस तरह सभी चीजों को प्रतिबंधित ।

आप तर्क दे सकते हैं कि सरल सीधे स्वंय काम के मामलों के लिए, यह भाषा कल्पना में किसी विशेष परिस्थिति में अच्छा होगा, लेकिन यह अपेक्षाकृत थोड़ा लाभ के लिए भाषा में जटिलता को पेश करेंगे।

ध्यान दें कि भले ही आप एक त्रुटि नहीं मिला, मैं तुम्हें एक चेतावनी प्राप्त करने के लिए उम्मीद थी - कुछ इस तरह:

Test.cs(3,33): warning CS1717: Assignment made to same variable; did you mean to assign something else?

भी ध्यान रखें कि यदि आप इसे एक const बजाय बनाने सिर्फ एक स्थिर केवल पढ़ने के लिए चर, तो आप एक संकलन समय त्रुटि मिलता है : .NET नामकरण सम्मेलनों द्वारा

Test.cs(3,23): error CS0110: The evaluation of the constant value for 'Program.QUARTER_HOUR_COUNT' involves a circular definition

इसके अलावा कि ध्यान दें, इसबुलाया जाना चाहिए SHOUTY_NAME होने के बजाय।

+1

असाइन किए गए चर का उपयोग मैंने सोचा होगा। – leppie

+3

@leppie: स्थिर क्षेत्र प्रारंभिक में स्थिर फ़ील्ड के लिए नहीं। शब्द "असाइन किए गए चर" स्थिर क्षेत्रों के लिए अप्रासंगिक है, जिसमें निश्चित असाइनमेंट की कोई अवधारणा नहीं है। –

+0

असल में, वे परिभाषित किए गए क्रम में प्रारंभ किए गए हैं। यह आईएमओ उस नियम को तोड़ देता है। – leppie

5

क्योंकि चर 0 के रूप में प्रारंभ किया गया था और फिर स्वयं को सेट किया गया था।

मेरा अनुमान है कि यह स्वयं को स्थापित करने से पहले एक नया Int() कर देगा जो इसे शून्य पर प्रारंभ करेगा।

4

क्योंकि संकलक नीचे इस लाइन टूट जाएगा: मूल रूप से की आईएल बराबर में

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

:

private static readonly int QUARTER_HOUR_COUNT; 
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

और फिर जाहिर है कि और अधिक भी टूट कर देंगे, लेकिन इसके बाद के संस्करण चाहिए मेरे बिंदु को चित्रित करने के लिए पर्याप्त है।

तो तकनीकी रूप से यह उपयोग होने पर शून्य के डिफ़ॉल्ट मान के साथ मौजूद होगा।

0

जैसा कि अन्य ने int जैसे मान प्रकारों को निहित किया है, एक डिफ़ॉल्ट मान है इसलिए स्पष्ट रूप से प्रारंभ किए बिना चर को घोषित करना मतलब है कि इसका अभी भी एक मान है।

तुम इतनी तरह किसी भी प्रकार के लिए डिफ़ॉल्ट मान पता कर सकते हैं:

int i = default(int); 

या अधिक आम तौर पर:

T t = default(T); 

ध्यान दें कि संदर्भ प्रकारों के लिए डिफ़ॉल्ट null हो जाएगा, केवल मूल्य प्रकार होगा डिफ़ॉल्ट मान हैं।

6

आईएल कोड द्वारा बनाया गया कोड यह है:

IL_0007: ldsfld  int32 Example.Quat::QUARTER_HOUR_COUNT//Load the value of a static field on the stack 
IL_000c: stsfld  int32 Example.Quat::QUARTER_HOUR_COUNT// Store the value from the stack in the static field 

के बाद से QUARTER_HOUR_COUNT का डिफ़ॉल्ट मान 0 है, 0

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