C # में const
और क्या अंतर readonly
है?
आप एक दूसरे पर कब इस्तेमाल करेंगे?
C # में const
और क्या अंतर readonly
है?
आप एक दूसरे पर कब इस्तेमाल करेंगे?
जवाबों:
के स्पष्ट अंतर के अलावा
const
VS readonly
मानों के लिए परिभाषा के समय मान की घोषणा गतिशील रूप से की जा सकती है, लेकिन कंस्ट्रक्टर के बाहर निकलने से पहले उसे असाइन करने की आवश्यकता होती है .. उसके बाद उसे फ्रीज किया जाता है।static
। आप ClassName.ConstantName
उन्हें एक्सेस करने के लिए एक नोटेशन का उपयोग करते हैं।सूक्ष्म अंतर है। में परिभाषित एक वर्ग पर विचार करें AssemblyA
।
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly int I_RO_VALUE;
public Const_V_Readonly()
{
I_RO_VALUE = 3;
}
}
AssemblyB
संदर्भ AssemblyA
और कोड में इन मूल्यों का उपयोग करता है। जब यह संकलित किया जाता है,
const
मान के मामले में , यह एक खोज-प्रतिस्थापित की तरह है, मान 2 को AssemblyB
's' IL में बेक किया गया है । इसका मतलब है कि अगर कल मैं I_CONST_VALUE
भविष्य में 20 अपडेट करूंगा । AssemblyB
मैं अभी भी 2 होगा जब तक मैं इसे recompile ।readonly
मान के मामले में , यह ref
एक मेमोरी लोकेशन की तरह है। मान को AssemblyB
IL में पकाया नहीं जाता है । इसका मतलब है कि यदि मेमोरी लोकेशन अपडेट किया गया है, AssemblyB
तो नए मूल्य को बिना रीकैपिलेशन के प्राप्त किया जाता है। इसलिए यदि I_RO_VALUE
30 तक अपडेट किया गया है, तो आपको केवल निर्माण करने की आवश्यकता है AssemblyA
। सभी क्लाइंट को recompiled करने की आवश्यकता नहीं है।इसलिए यदि आप आश्वस्त हैं कि स्थिरांक का मूल्य नहीं बदलेगा तो a const
।
public const int CM_IN_A_METER = 100;
लेकिन अगर आपके पास एक स्थिरांक है जो बदल सकता है (उदाहरण के लिए सटीक) .. या संदेह में होने पर, एक का उपयोग करें readonly
।
public readonly float PI = 3.14;
अद्यतन: अकु को एक उल्लेख coz प्राप्त करने की आवश्यकता है जो उन्होंने पहले बताया। मुझे यह भी प्लग करने की आवश्यकता है जहां मैंने यह सीखा .. प्रभावी C # - बिल वैगनर
static
- बिंदु सबसे महत्वपूर्ण और उपयोगी बिंदु हो रहा हैconsts are implicitly static
readonly
कंस्ट्रक्टर (प्रतिबिंब) के बाहर चर बदले जा सकते हैं। यह केवल संकलक है जो आपको कंस्ट्रक्टर के बाहर के संस्करण को संशोधित करने से रोकने की कोशिश करता है।
readonly
वेरिएबल्स को कंस्ट्रक्टर के समाप्त होने के बाद भी बदलने की अनुमति नहीं है, यहां तक कि प्रतिबिंब के माध्यम से भी। रनटाइम ऐसा नहीं करने के लिए होता है। क्रम भी लागू करने के लिए है कि आप में परिवर्तन नहीं करते नहीं होता है string.Empty
करने के लिए "Hello, world!"
, लेकिन मैं अभी भी यह दावा नहीं है कि यह बनाता है string.Empty
परिवर्तनीय, या कि कोड नहीं मानना चाहिए कि string.Empty
हमेशा एक शून्य लंबाई स्ट्रिंग होगा।
कब्ज़ के साथ एक गोत्र है! यदि आप किसी अन्य असेंबली से किसी स्थिरांक को संदर्भित करते हैं, तो इसका मान कॉलिंग असेंबली में संकलित किया जाएगा। इस तरह से जब आप संदर्भित विधानसभा में निरंतर अद्यतन करते हैं तो यह कॉलिंग असेंबली में नहीं बदलेगा!
सिर्फ जोड़ने के लिए, ReadOnly संदर्भ प्रकारों के लिए केवल संदर्भ को आसानी से मानों को नहीं बनाता है। उदाहरण के लिए:
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};
public UpdateReadonly()
{
I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
I_RO_VALUE = new char[]{'V'}; //will cause compiler error
}
}
string
जिसे आप एक स्थिर के रूप में उपयोग कर सकते हैं?
const
स्ट्रिंग के अलावा अन्य संदर्भ प्रकार हो सकते हैं , लेकिन स्थिरांक का केवल मूल्य हो सकता है null
।
यह बताते हैं । सारांश: कॉन्स्टेंस को घोषणा के समय आरंभीकृत किया जाना चाहिए, आसानी से कंस्ट्रक्टर पर आरंभीकृत किया जा सकता है (और इस प्रकार उपयोग किए गए कंस्ट्रक्टर के आधार पर एक अलग मूल्य है)।
संपादित करें: सूक्ष्म अंतर के लिए ऊपर गिशु का गोच देखें
एक छोटा सा गोटा है जिसमें आसानी से पढ़ा जा सकता है। एक रीडोनॉली फ़ील्ड को कंस्ट्रक्टर (एस) के भीतर कई बार सेट किया जा सकता है। भले ही मूल्य दो अलग-अलग जंजीरों वाले निर्माणों में सेट किया गया हो, फिर भी इसकी अनुमति है।
public class Sample {
private readonly string ro;
public Sample() {
ro = "set";
}
public Sample(string value) : this() {
ro = value; // this works even though it was set in the no-arg ctor
}
}
एक निरंतर सदस्य को संकलित समय पर परिभाषित किया जाता है और रनटाइम में नहीं बदला जा सकता है। कॉन्स्टेंट को एक क्षेत्र के रूप में घोषित किया जाता है, const
कीवर्ड का उपयोग करते हुए उन्हें घोषित किया जाना चाहिए।
public class MyClass
{
public const double PI1 = 3.14159;
}
एक readonly
सदस्य एक निरंतर की तरह है कि यह अपरिवर्तनीय मूल्य का प्रतिनिधित्व करता है। अंतर यह है कि एक readonly
सदस्य को रनटाइम में, एक कंस्ट्रक्टर में आरंभीकृत किया जा सकता है, साथ ही उन्हें घोषित किए जाने के लिए आरंभिक रूप से सक्षम किया जा सकता है।
public class MyClass1
{
public readonly double PI2 = 3.14159;
//or
public readonly double PI3;
public MyClass2()
{
PI3 = 3.14159;
}
}
स्थिरांक
static
(वे स्पष्ट रूप से स्थिर हैं)सिफ़ पढ़िये
static const int i = 0;
const
घोषणाएँ विधियों के अंदर क्यों नहीं की जा सकतीं?
एक कॉन्सल एक संकलन-समय स्थिर है, जबकि आसानी से रन-टाइम पर एक वैल्यू की गणना की जाती है और कंस्ट्रक्टर या फील्ड एडवाइजर में सेट की जाती है। इसलिए, एक 'कॉन्स्टेंट' हमेशा स्थिर होता है लेकिन 'रीडऑनली' केवल एक बार पढ़ा जाता है।
C # टीम के एरिक लिपर्ट के पास विभिन्न प्रकार की अपरिवर्तनीयता के बारे में अधिक जानकारी है
यह दिखाने के लिए कि लिंक कैसे सुरक्षित नहीं है, या संदर्भ प्रकारों के लिए प्रासंगिक एक और लिंक यहां दिया गया है ।
सारांश :
Read Only : रनटाइम के समय Ctor के माध्यम से मूल्य को बदला जा सकता है लेकिन मेंबर फंक्शन के जरिए नहीं
लगातार : स्थिर द्वारा रक्षा। मान को कहीं से भी नहीं बदला जा सकता (Ctor, Function, runtime etc no-जहाँ)
अभी तक एक और गोटा: प्रतिबिंब के माध्यम से "कुटिल" कोड द्वारा आसानी से मूल्यों को बदला जा सकता है।
var fi = this.GetType()
.BaseType
.GetField("_someField",
BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);
क्या मैं प्रतिबिंब का उपयोग करके C # में एक निजी पठनीय विरासत में मिला क्षेत्र बदल सकता हूँ?
हमारे कार्यालय में टीम के सदस्यों में से एक ने कॉन्स्टेबल, स्टेटिक और आसानी से उपयोग करने के बारे में निम्नलिखित मार्गदर्शन प्रदान किया:
एक अंतिम नोट: एक कास्ट फील्ड स्थिर है, लेकिन व्युत्क्रम सत्य नहीं है।
वे दोनों निरंतर हैं, लेकिन संकलन समय पर भी उपलब्ध है। इसका मतलब यह है कि अंतर का एक पहलू यह है कि आप कंस्ट्रक्शन कंस्ट्रक्टर्स के इनपुट के रूप में कॉन्स्टेबल वेरिएबल का उपयोग कर सकते हैं, लेकिन आसानी से वेरिएबल नहीं।
उदाहरण:
public static class Text {
public const string ConstDescription = "This can be used.";
public readonly static string ReadonlyDescription = "Cannot be used.";
}
public class Foo
{
[Description(Text.ConstDescription)]
public int BarThatBuilds {
{ get; set; }
}
[Description(Text.ReadOnlyDescription)]
public int BarThatDoesNotBuild {
{ get; set; }
}
}
कब उपयोग करें const
याreadonly
const
readonly
App.config
, लेकिन एक बार इसे शुरू करने के बाद इसे बदला नहीं जा सकता हैवैरिएबल चिह्नित कॉस्ट दृढ़ता से टाइप किए गए #define मैक्रोज़ से थोड़ा अधिक हैं, संकलन समय पर कॉन्सल चर संदर्भों को इनलाइन शाब्दिक मानों के साथ बदल दिया जाता है। एक परिणाम के रूप में केवल कुछ अंतर्निर्मित आदिम मूल्य प्रकार इस तरह से उपयोग किए जा सकते हैं। आसानी से चिह्नित वेरिएबल्स को एक कंस्ट्रक्टर में, रन-टाइम पर सेट किया जा सकता है और रन-टाइम के दौरान उनका रीड-ओनली-नेस लागू किया जाता है। इससे जुड़ी कुछ मामूली प्रदर्शन लागत है लेकिन इसका मतलब है कि आप किसी भी प्रकार (यहां तक कि संदर्भ प्रकार) के साथ आसानी से उपयोग कर सकते हैं।
इसके अलावा, कांस्टेबल चर स्वाभाविक रूप से स्थिर होते हैं, जबकि वांछित होने पर पठनीय चर विशिष्ट हो सकते हैं।
एक और गच्चा ।
चूंकि कॉन्स्ट वास्तव में केवल बुनियादी डेटा प्रकारों के साथ काम करता है, यदि आप एक वर्ग के साथ काम करना चाहते हैं, तो आप ReadOnly का उपयोग करने के लिए "मजबूर" महसूस कर सकते हैं। हालाँकि, जाल से सावधान रहें! ReadOnly का अर्थ है कि आप ऑब्जेक्ट को किसी अन्य ऑब्जेक्ट से बदल नहीं सकते (आप इसे किसी अन्य ऑब्जेक्ट को संदर्भित नहीं कर सकते)। लेकिन किसी भी प्रक्रिया में ऑब्जेक्ट के संदर्भ में ऑब्जेक्ट के अंदर मूल्यों को संशोधित करने के लिए स्वतंत्र है !
इसलिए यह सोचकर भ्रमित न हों कि ReadOnly का तात्पर्य है कि उपयोगकर्ता चीजों को बदल नहीं सकता है। किसी वर्ग की तात्कालिकता को उसके आंतरिक मूल्यों को बदलने से रोकने के लिए सी # में कोई सरल वाक्यविन्यास नहीं है (जहाँ तक मुझे पता है)।
C # .Net में कांस्ट और पठनीय क्षेत्रों के बीच उल्लेखनीय अंतर है
कॉन्स्ट डिफ़ॉल्ट रूप से स्थिर है और इसे निरंतर मूल्य के साथ आरंभ करने की आवश्यकता है, जिसे बाद में संशोधित नहीं किया जा सकता है। रचनाकारों में भी मूल्य परिवर्तन की अनुमति नहीं है। इसका उपयोग सभी डेटाटिप्स के साथ नहीं किया जा सकता है। पूर्व तिथि के लिए। इसका उपयोग DateTime डेटाटाइप के साथ नहीं किया जा सकता है।
public const DateTime dt = DateTime.Today; //throws compilation error
public const string Name = string.Empty; //throws compilation error
public readonly string Name = string.Empty; //No error, legal
आसानी से स्थिर के रूप में घोषित किया जा सकता है, लेकिन आवश्यक नहीं है। घोषणा के समय आरंभ करने की आवश्यकता नहीं है। इसके मूल्य को कंस्ट्रक्टर का उपयोग करके सौंपा या बदला जा सकता है। इसलिए, यह लाभ देता है जब उदाहरण वर्ग के सदस्य के रूप में उपयोग किया जाता है। दो अलग-अलग तात्कालिकता में पठनीय क्षेत्र के अलग-अलग मूल्य हो सकते हैं। पूर्व के लिए -
class A
{
public readonly int Id;
public A(int i)
{
Id = i;
}
}
फिर तत्काल विशिष्ट मानों के साथ आसानी से फ़ील्ड को आरंभ किया जा सकता है:
A objOne = new A(5);
A objTwo = new A(10);
यहाँ, उदाहरण objOne में 5 के रूप में आसानी से फ़ील्ड का मान होगा और objTwo में 10 है। जो कि const का उपयोग करना संभव नहीं है।
एक स्थिर को उपभोक्ता में शाब्दिक मूल्य के रूप में संकलित किया जाएगा जबकि स्थिर स्ट्रिंग परिभाषित मूल्य के संदर्भ के रूप में काम करेगा।
एक अभ्यास के रूप में, एक बाहरी पुस्तकालय बनाने की कोशिश करें और इसे एक कंसोल एप्लिकेशन में उपभोग करें, फिर लाइब्रेरी में मूल्यों को बदल दें और इसे फिर से जोड़ें (उपभोक्ता कार्यक्रम को फिर से शुरू किए बिना), DLL को निर्देशिका में छोड़ दें और मैन्युअल रूप से EXE चलाएं, आपको मिलना चाहिए निरंतर स्ट्रिंग परिवर्तित नहीं होती है।
लगातार
जब परिभाषित किया जाता है तो हमें कॉस्ट फ़ील्ड को मान प्रदान करना होगा। संकलक तब असेंबली के मेटाडेटा में निरंतर मान बचाता है। इसका मतलब यह है कि एक स्थिरांक को केवल आदिम प्रकार जैसे कि बूलियन, चार, बाइट और इसी तरह के लिए परिभाषित किया जा सकता है। स्थिरांक हमेशा स्थिर सदस्य माने जाते हैं, उदाहरण के सदस्य नहीं।
सिफ़ पढ़िये
केवल पठनीय क्षेत्रों को रनटाइम पर हल किया जा सकता है। इसका मतलब है कि हम उस प्रकार के लिए कंस्ट्रक्टर का उपयोग करके एक मान को परिभाषित कर सकते हैं जिसमें फ़ील्ड घोषित किया गया है। सत्यापन कम्पाइलर द्वारा किया जाता है कि आसानी से खेतों को कंस्ट्रक्टर के अलावा किसी अन्य विधि से नहीं लिखा जाता है।
दोनों के बारे में अधिक इस लेख में यहाँ बताया गया है
कॉन्स्ट और पठनीय समान हैं, लेकिन वे बिल्कुल समान नहीं हैं। एक कास्ट फ़ील्ड एक संकलन-समय स्थिर है, जिसका अर्थ है कि संकलन-समय पर उस मूल्य की गणना की जा सकती है। एक पठनीय क्षेत्र अतिरिक्त परिदृश्यों को सक्षम करता है जिसमें प्रकार के निर्माण के दौरान कुछ कोड चलाने चाहिए। निर्माण के बाद, आसानी से एक फ़ील्ड नहीं बदला जा सकता है।
उदाहरण के लिए, कास्ट मेंबर का इस्तेमाल सदस्यों को परिभाषित करने के लिए किया जा सकता है:
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 = r;
green = g;
blue = b;
}
}
लेकिन फिर इसके साथ मैकिंग से कलर के ग्राहक रखने के लिए कुछ भी नहीं है, शायद ब्लैक एंड व्हाइट मूल्यों को स्वैप करके। कहने की जरूरत नहीं है, इससे रंग वर्ग के अन्य ग्राहकों के लिए अड़चन पैदा होगी। "आसानी से" सुविधा इस परिदृश्य को संबोधित करती है। केवल घोषणाओं में आसानी से कीवर्ड की शुरुआत करके, हम ग्राहक कोड को आसपास से रोकने से लचीला आरंभीकरण को संरक्षित करते हैं।
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 = r;
green = g;
blue = 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 हमेशा शून्य रहेगा। दोनों कांस्टेबल का उपयोग और आसानी से ए के डेवलपर को इरादा निर्दिष्ट करने की अनुमति देता है। यह बेहतर संस्करण व्यवहार और बेहतर प्रदर्शन के लिए बनाता है।
अंतर यह है कि एक स्थिर पठनीय क्षेत्र का मान रन टाइम पर सेट किया जाता है, इसलिए इसमें प्रोग्राम के विभिन्न निष्पादन के लिए एक अलग मूल्य हो सकता है। हालाँकि, एक कास्ट फ़ील्ड का मान एक स्थिर समय स्थिर करने के लिए सेट किया गया है।
याद रखें: संदर्भ प्रकारों के लिए, दोनों मामलों में (स्थिर और उदाहरण), केवल पढ़ने योग्य संशोधक आपको फ़ील्ड के लिए एक नया संदर्भ निर्दिष्ट करने से रोकता है। यह विशेष रूप से संदर्भ द्वारा इंगित वस्तु को अपरिवर्तनीय नहीं बनाता है।
जानकारी के लिए, कृपया इस विषय पर C # अक्सर पूछे जाने वाले प्रश्न देखें: http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx
लगातार चर घोषित किए जाते हैं और संकलन समय पर शुरू हो जाते हैं। वार्ड के बाद मान को बदला नहीं जा सकता। रीड-ओनली वेरिएबल को केवल क्लास के स्टैटिक कंस्ट्रक्टर से इनिशियलाइज़ किया जाएगा। केवल तभी उपयोग किया जाता है जब हम रन टाइम पर मान असाइन करना चाहते हैं।
कास्ट : आवेदन जीवन समय के दौरान पूर्ण स्थिर मूल्य।
Readonly : इसे रनिंग टाइम में बदला जा सकता है।
एक बात जो लोगों ने ऊपर कही है उसे जोड़ने के लिए। यदि आपके पास एक असेंबली है जिसमें रीडॉनली वैल्यू है (उदाहरण के लिए MaxFooCount = 4;), तो आप उस असेंबली को एक अलग मूल्य के साथ उस असेंबली के नए संस्करण को शिपिंग करके देख सकने वाले मान को बदल सकते हैं (उदाहरण के लिए MaxFooCount = 5;)।
लेकिन एक कास्ट के साथ, यह कॉलर के कोड में बदल जाएगा जब कॉलर संकलित किया गया था।
यदि आप C # प्रवीणता के इस स्तर पर पहुँच गए हैं, तो आप Bill Wagner की पुस्तक के लिए तैयार हैं, प्रभावी C #: 50 आपके C को बेहतर बनाने के विशिष्ट तरीके # जो इस प्रश्न का उत्तर विस्तार से देते हैं, (और 49 अन्य बातों का)।