C# specification, chapter 10.4 - Constants से: जो कर सकते हैं एक मूल्य:
(सी # 3.0 विनिर्देश में 10.4, 10.3 2.0 के लिए ऑनलाइन संस्करण में)
एक निरंतर एक वर्ग के सदस्य है कि एक निरंतर मूल्य का प्रतिनिधित्व करता है संकलन समय पर गणना कीजिए।
यह मूल रूप से कहता है कि आप केवल उन अभिव्यक्तियों का उपयोग कर सकते हैं जिनमें केवल शाब्दिक शामिल हैं। किसी भी तरीके, कन्स्ट्रक्टर (जिसे शुद्ध आईएल अक्षरों के रूप में प्रदर्शित नहीं किया जा सकता) के लिए कोई भी कॉल का उपयोग नहीं किया जा सकता है, क्योंकि संकलक को निष्पादन करने का कोई तरीका नहीं है, और इस प्रकार संकलन समय पर परिणामों की गणना करें। इसके अलावा, चूंकि किसी विधि को इनवेरिएंट के रूप में टैग करने का कोई तरीका नहीं है (यानी।इनपुट और आउटपुट के बीच एक-से-एक मैपिंग है), ऐसा करने के लिए कंपाइलर का एकमात्र तरीका या तो आईएल का विश्लेषण करना होगा कि यह इनपुट पैरामीटर के अलावा अन्य चीज़ों पर निर्भर करता है, विशेष केस कुछ प्रकार हैंडल करता है (IntPtr की तरह), या किसी भी कोड पर हर कॉल को अस्वीकार करें।
IntPtr, एक उदाहरण के रूप में, एक मूल्य प्रकार होने के बावजूद, अभी भी एक संरचना है, और अंतर्निहित अक्षरों में से एक नहीं है। इस प्रकार, इंटप्राट का उपयोग करने वाली किसी भी अभिव्यक्ति को इंटिप्ट संरचना में कोड कॉल करने की आवश्यकता होगी, और यह निरंतर घोषणा के लिए कानूनी नहीं है।
एकमात्र कानूनी निरंतर मूल्य प्रकार उदाहरण मैं सोच सकता हूं कि शून्य के साथ इसे घोषित करके शुरू किया जाएगा, और यह शायद ही उपयोगी है।
कंपाइलर कैसे स्थिरांक का उपयोग/उपयोग करता है, यह कोड में निरंतर नाम के स्थान पर गणना मूल्य का उपयोग करेगा।
इस प्रकार, आप निम्नलिखित प्रभाव है:
- मूल निरंतर नाम करने के लिए कोई संदर्भ, वर्ग उस में घोषित किया गया था, या नाम स्थान, इस स्थान
- में कोड में संकलित किया गया है आप डिकंपाइल हैं कोड में, इसमें जादू संख्याएं होंगी, क्योंकि केवल ऊपर वर्णित मूल "संदर्भ" है, वर्तमान में नहीं, केवल
- का मान संकलक इसे अनुकूलित करने या यहां तक कि निकालने के लिए उपयोग कर सकता है, अनावश्यक कोड उदाहरण के लिए,
if (SomeClass.Version == 1)
, जब SomeClass.Version का मान 1 है, वास्तव में if-statement को हटा देगा, और कोड के ब्लॉक को निष्पादित किया जाएगा। यदि स्थिरांक का मान 1 नहीं है, तो संपूर्ण if-statement और उसका ब्लॉक हटा दिया जाएगा।
- चूंकि निरंतर के मान को कोड में संकलित किया गया है, और निरंतर संदर्भ नहीं है, अन्य असेंबली से स्थिरांक का उपयोग करके संकलित कोड को किसी भी तरह से स्वचालित रूप से अपडेट नहीं किया जाएगा यदि स्थिरता का मूल्य बदलना चाहिए (जिसे इसे करना चाहिए नहीं)
दूसरे शब्दों में, इस परिदृश्य के साथ:
- विधानसभा ए, "संस्करण" नाम के एक निरंतर, 1
- विधानसभा बी के एक मूल्य के लिए होने शामिल है, एक अभिव्यक्ति है, जो उस निरंतर ए से असेंबली ए के संस्करण संख्या का विश्लेषण करता है nd यह 1 की तुलना में, 2 के लिए निरंतर की कीमत बढ़ यकीन है कि यह विधानसभा
- किसी को संशोधित करता विधानसभा एक साथ काम कर सकते बनाने के लिए, और पुनर्निर्माण एक (लेकिन बी)
इस मामले में, असेंबली बी, इसके संकलित रूप में, अभी भी 1 से 1 के मान की तुलना करेगा, क्योंकि जब बी संकलित किया गया था, तो स्थिरांक का मूल्य 1.
वास्तव में, यदि यह असेंबली ए से कुछ भी उपयोग है असेंबली बी, असेंबली बी को असेंबली ए पर निर्भरता के बिना संकलित किया जाएगा। असेंबली बी में उस अभिव्यक्ति वाले कोड को निष्पादित करना असेंबली ए लोड नहीं करेगा।
कॉन्स्टेंट्स को केवल उन चीजों के लिए उपयोग किया जाना चाहिए जो कभी नहीं बदलेगा। यदि यह एक ऐसा मूल्य है जो भविष्य में कुछ समय बदल सकता है या बदल सकता है, और आप गारंटी नहीं दे सकते कि अन्य सभी असेंबली एक साथ पुनर्निर्मित की जाती हैं, तो एक पठनीय क्षेत्र निरंतर से अधिक उपयुक्त होता है।
तो यह ठीक है:
- सार्वजनिक स्थिरांक Int32 NumberOfDaysInAWeekInGregorianCalendar = 7;
- सार्वजनिक कॉन्स Int32 NumberOfHoursInADayOnEarth = 24;
इस जबकि नहीं है:
- सार्वजनिक स्थिरांक Int32 AgeOfProgrammer = 25;
- सार्वजनिक कॉन्स स्ट्रिंग नामऑफलास्टप्रोग्रामरैटमोडिफाइडएस्क्रिप्ट्स = "जो प्रोग्रामर";
संपादित कर सकते हैं 27 वें वर्ष 2016
ठीक है, सिर्फ एक वोट दें मिला है, इसलिए मैं अपने जवाब यहाँ फिर से पढ़ सकते हैं और यह वास्तव में थोड़ा गलत है।
अब, सी # भाषा विनिर्देश के इरादे सब कुछ मैंने ऊपर लिखा है। आपको ऐसा कुछ उपयोग नहीं करना चाहिए जिसे const
के रूप में शाब्दिक के साथ प्रदर्शित नहीं किया जा सकता है।
लेकिन क्या आप कर सकते हैं? खैर, हाँ ....
चलो decimal
प्रकार पर एक नज़र डालें।
.field public static initonly valuetype [mscorlib]System.Decimal X
.custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(int8, uint8, uint32, uint32, uint32) = (01 00 01 00 00 00 00 00 00 00 00 00 64 00 00 00 00 00)
मुझे यह आप के लिए तोड़ने के नीचे दो::
.field public static initonly
से मेल खाती है:
public class Test
{
public const decimal Value = 10.123M;
}
के इस वर्ग के वास्तव में जब ILDASM साथ को देखा कैसा दिखता है पर नजर डालते हैं
public static readonly
यह सही है, const decimal
वास्तव में readonly decimal
है।
असली सौदा यह है कि संकलक DecimalConstantAttribute
का उपयोग अपने जादू के लिए करेगा।
अब, यह एकमात्र ऐसा जादू है जिसे मैं सी # कंपाइलर के साथ जानता हूं लेकिन मैंने सोचा कि यह उल्लेखनीय है।
जाहिर है आप यह नहीं कर सकते हैं लेकिन * hypothetically बोलते हुए *, कहते हैं कि हमारे पास एक मूल्य-प्रकार-लौटने वाली स्थिर विधि थी जिसे [शुद्ध] विशेषता के साथ चिह्नित किया गया था और संकलक वास्तव में इसे लागू करता है (यह वर्तमान में नहीं है)। क्या भाषा डिजाइनर कम से कम * सैद्धांतिक रूप से * स्थिर मूल्य-प्रकार-लौटने वाली शुद्ध विधि (वास्तविक [शुद्ध] विशेषता प्रवर्तन के साथ) को तब तक शुरू कर सकते हैं जब तक कि तर्क कुछ भी नहीं बल्कि शाब्दिक थे? ऐसा लगता है कि वे इसे शाब्दिक तर्कों के साथ चला सकते हैं, परिणाम प्राप्त करें जो स्पष्ट रूप से बदलने के लिए नहीं जा रहा है और मूल्य में उप है। क्या मैं कुछ देख रहा हूँ? –
'इस मामले में, असेंबली बी, इसके संकलित रूप में, अभी भी 1 से 1 के मान की तुलना करेगा, क्योंकि जब बी संकलित किया गया था, तो निरंतर मान 1 था - आप अभी भी वही चीज़ कर सकते हैं जो' सार्वजनिक आधार int विधानसभा संस्करण = 1' आज किसी भी सी # संस्करण में, इसलिए संरचनाओं के साथ कुछ भी गलत नहीं है * खुद –