const
और readonly
समान हैं, लेकिन वे समान नहीं हैं।
एक const
क्षेत्र एक संकलन-समय स्थिर है, जिसका अर्थ है कि संकलन-समय पर उस मूल्य की गणना की जा सकती है। एक readonly
फ़ील्ड अतिरिक्त परिदृश्यों को सक्षम करता है जिसमें प्रकार के निर्माण के दौरान कुछ कोड चलना चाहिए। निर्माण के बाद, एक readonly
फ़ील्ड नहीं बदला जा सकता है।
उदाहरण के लिए, const
सदस्यों का उपयोग सदस्यों को परिभाषित करने के लिए किया जा सकता है:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
चूंकि 3.14 और 0 जैसे मूल्य संकलन-समय स्थिरांक हैं। हालांकि, उस मामले पर विचार करें जहां आप एक प्रकार को परिभाषित करते हैं और इसके कुछ पूर्व-फैब उदाहरण प्रदान करना चाहते हैं। उदाहरण के लिए, आप एक रंग वर्ग को परिभाषित करना चाहते हैं और काले, सफेद, आदि जैसे सामान्य रंगों के लिए "स्थिरांक" प्रदान कर सकते हैं, यह संभव नहीं है कि यह कांस्ट सदस्यों के साथ करें, क्योंकि दाहिने हाथ के पक्ष संकलन-समय स्थिरांक नहीं हैं। कोई नियमित स्थैतिक सदस्यों के साथ ऐसा कर सकता है:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
लेकिन फिर इसके साथ मैकिंग से कलर के क्लाइंट को रखने के लिए कुछ भी नहीं है, शायद ब्लैक एंड व्हाइट मूल्यों को स्वैप करके। कहने की जरूरत नहीं है, इससे रंग वर्ग के अन्य ग्राहकों के लिए अड़चन पैदा होगी। "आसानी से" सुविधा इस परिदृश्य को संबोधित करती है।
केवल readonly
घोषणाओं में कीवर्ड को शुरू करने से , हम क्लाइंट कोड को आसपास से रोकने से रोकते हुए लचीली आरंभीकरण को संरक्षित करते हैं।
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
यह ध्यान रखना दिलचस्प है कि कॉन्स्टेबल सदस्य हमेशा स्थिर होते हैं, जबकि एक नियमित सदस्य एक नियमित क्षेत्र की तरह या तो स्थिर हो सकता है या नहीं।
इन दोनों उद्देश्यों के लिए एक ही कीवर्ड का उपयोग करना संभव है, लेकिन इससे या तो संस्करण संबंधी समस्याएं या प्रदर्शन समस्याएं होती हैं। उस क्षण के लिए मान लें कि हमने इस (कॉन्स्टेबल) और डेवलपर के लिए एक एकल कीवर्ड का उपयोग किया है:
public class A
{
public static const C = 0;
}
और एक अलग डेवलपर ने कोड लिखा है जो A पर निर्भर है:
public class B
{
static void Main() => Console.WriteLine(A.C);
}
अब, उत्पन्न होने वाला कोड इस बात पर भरोसा कर सकता है कि एसी एक संकलन-समय स्थिर है? यानी, क्या AC का उपयोग केवल मान 0 से बदला जा सकता है? यदि आप इसके लिए "हाँ" कहते हैं, तो इसका मतलब है कि A का डेवलपर उस तरह से बदलाव नहीं कर सकता है जैसे AC को इनिशियलाइज़ किया जाता है - यह A के डेवलपर के हाथों को बिना अनुमति के रखता है।
यदि आप इस प्रश्न के लिए "नहीं" कहते हैं तो एक महत्वपूर्ण अनुकूलन छूट जाता है। शायद A का लेखक सकारात्मक है कि AC हमेशा शून्य रहेगा। दोनों कांस्टेबल का उपयोग और आसानी से ए के डेवलपर को इरादा निर्दिष्ट करने की अनुमति देता है। यह बेहतर संस्करण व्यवहार और बेहतर प्रदर्शन के लिए बनाता है।
static readonly
: एक कास्ट का उपयोग करने का प्रयास करें,IEnumerator
जो एक अप्राप्य को ट्रिगर करेगाyield
और आपको एक खतरनाक "आंतरिक संकलक त्रुटि" मिलेगी । मैंने यूनिटी 3 डी के बाहर कोड का परीक्षण नहीं किया, लेकिन मुझे विश्वास है कि यह मोनो या .NET बग है । यह एक c # मुद्दा है।