C और # में आसानी से अंतर के बीच अंतर क्या है?


1361

C # में constऔर क्या अंतर readonlyहै?

आप एक दूसरे पर कब इस्तेमाल करेंगे?


मुझे इस लिंक को खोजने के लिए कई उत्तरों को देखना पड़ा, लेकिन यह एक अच्छा है। एरिक लिपर्ट का सी # में अपरिवर्तनीयता पर कब्जा
फ्रैंक ब्राइस

2
@donstack, वास्तव में C # संदर्भ के अनुसार , क्षेत्र की घोषणा और कंस्ट्रक्टर के भीतर एक
Marques

जवाबों:


1289

के स्पष्ट अंतर के अलावा

  • constVS 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एक मेमोरी लोकेशन की तरह है। मान को AssemblyBIL में पकाया नहीं जाता है । इसका मतलब है कि यदि मेमोरी लोकेशन अपडेट किया गया है, AssemblyBतो नए मूल्य को बिना रीकैपिलेशन के प्राप्त किया जाता है। इसलिए यदि I_RO_VALUE30 तक अपडेट किया गया है, तो आपको केवल निर्माण करने की आवश्यकता है AssemblyA। सभी क्लाइंट को recompiled करने की आवश्यकता नहीं है।

इसलिए यदि आप आश्वस्त हैं कि स्थिरांक का मूल्य नहीं बदलेगा तो a const

public const int CM_IN_A_METER = 100;

लेकिन अगर आपके पास एक स्थिरांक है जो बदल सकता है (उदाहरण के लिए सटीक) .. या संदेह में होने पर, एक का उपयोग करें readonly

public readonly float PI = 3.14;

अद्यतन: अकु को एक उल्लेख coz प्राप्त करने की आवश्यकता है जो उन्होंने पहले बताया। मुझे यह भी प्लग करने की आवश्यकता है जहां मैंने यह सीखा .. प्रभावी C # - बिल वैगनर


77
static- बिंदु सबसे महत्वपूर्ण और उपयोगी बिंदु हो रहा हैconsts are implicitly static
LCJ

28
संदर्भ मूल्यों के बारे में हिस्सा सबसे महत्वपूर्ण है। लगातार मूल्यों को दूर किया जा सकता है।
कोडिंगबारफील्ड

22
readonlyकंस्ट्रक्टर (प्रतिबिंब) के बाहर चर बदले जा सकते हैं। यह केवल संकलक है जो आपको कंस्ट्रक्टर के बाहर के संस्करण को संशोधित करने से रोकने की कोशिश करता है।
Bitterblue

12
@ मिनी-मी readonlyवेरिएबल्स को कंस्ट्रक्टर के समाप्त होने के बाद भी बदलने की अनुमति नहीं है, यहां तक ​​कि प्रतिबिंब के माध्यम से भी। रनटाइम ऐसा नहीं करने के लिए होता है। क्रम भी लागू करने के लिए है कि आप में परिवर्तन नहीं करते नहीं होता है string.Emptyकरने के लिए "Hello, world!", लेकिन मैं अभी भी यह दावा नहीं है कि यह बनाता है string.Emptyपरिवर्तनीय, या कि कोड नहीं मानना चाहिए कि string.Emptyहमेशा एक शून्य लंबाई स्ट्रिंग होगा।

7
blogs.msmvps.com/jonskeet/2014/07/16/… एक दिलचस्प रीड ओनली ओवरहेड लागत है
सीएडी ब्लॉके

275

कब्ज़ के साथ एक गोत्र है! यदि आप किसी अन्य असेंबली से किसी स्थिरांक को संदर्भित करते हैं, तो इसका मान कॉलिंग असेंबली में संकलित किया जाएगा। इस तरह से जब आप संदर्भित विधानसभा में निरंतर अद्यतन करते हैं तो यह कॉलिंग असेंबली में नहीं बदलेगा!


8
अपघटन (परावर्तक, ILSpy, ..) पर कभी भी किसी भी व्यक्ति द्वारा संदर्भित नहीं किया जाता है, समान असेंबली या किसी अन्य असेंबली का कोई भी मामला नहीं होता है, इसलिए आप संकलित कोड में स्थिरांक के उपयोग का विश्लेषण नहीं कर सकते हैं।
बसंती 76६

159

स्थिरांक

  • लगातार डिफ़ॉल्ट रूप से स्थिर होते हैं
  • उनके पास संकलन-समय पर एक मूल्य होना चाहिए (आप उदाहरण के लिए 3.14 * 2 हो सकते हैं, लेकिन तरीकों को कॉल नहीं कर सकते)
  • कार्यों के भीतर घोषित किया जा सकता है
  • प्रत्येक विधानसभा में उनकी नकल की जाती है जो उनका उपयोग करती है (प्रत्येक विधानसभा को मूल्यों की एक स्थानीय प्रति मिलती है)
  • विशेषताओं में इस्तेमाल किया जा सकता है

क्षेत्रों को आसानी से पढ़ें

  • समय निर्माता द्वारा बाहर निकलने से मूल्य निर्धारित किया जाना चाहिए
  • मूल्यांकन किया जाता है जब उदाहरण बनाया जाता है

स्थैतिक आसानी से खेतों

  • मूल्यांकन किया जाता है जब कोड निष्पादन वर्ग संदर्भ को हिट करता है (जब नया उदाहरण बनाया जाता है या एक स्थिर विधि निष्पादित की जाती है)
  • स्थिर कंस्ट्रक्टर किए जाने के समय का मूल्यांकन मूल्य होना चाहिए
  • इन पर थ्रेडस्टैटिक एट्रिब्यूट लगाने की अनुशंसा नहीं की जाती है (स्थिर कंस्ट्रक्टर को केवल एक थ्रेड में निष्पादित किया जाएगा और इसके थ्रेड के लिए मान सेट करेगा; अन्य सभी थ्रेड्स में यह मान एकरहित होगा)

58

सिर्फ जोड़ने के लिए, 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जिसे आप एक स्थिर के रूप में उपयोग कर सकते हैं?
बसंती 76६

आपके पास constस्ट्रिंग के अलावा अन्य संदर्भ प्रकार हो सकते हैं , लेकिन स्थिरांक का केवल मूल्य हो सकता है null
बजे माइक रोसॉफ्ट

40

यह बताते हैं । सारांश: कॉन्स्टेंस को घोषणा के समय आरंभीकृत किया जाना चाहिए, आसानी से कंस्ट्रक्टर पर आरंभीकृत किया जा सकता है (और इस प्रकार उपयोग किए गए कंस्ट्रक्टर के आधार पर एक अलग मूल्य है)।

संपादित करें: सूक्ष्म अंतर के लिए ऊपर गिशु का गोच देखें


32

const: कहीं भी बदला नहीं जा सकता।

readonly: यह मान केवल कंस्ट्रक्टर में बदला जा सकता है। सामान्य कार्यों में नहीं बदला जा सकता है।


26

एक छोटा सा गोटा है जिसमें आसानी से पढ़ा जा सकता है। एक रीडोनॉली फ़ील्ड को कंस्ट्रक्टर (एस) के भीतर कई बार सेट किया जा सकता है। भले ही मूल्य दो अलग-अलग जंजीरों वाले निर्माणों में सेट किया गया हो, फिर भी इसकी अनुमति है।


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
    }
}

26

एक निरंतर सदस्य को संकलित समय पर परिभाषित किया जाता है और रनटाइम में नहीं बदला जा सकता है। कॉन्स्टेंट को एक क्षेत्र के रूप में घोषित किया जाता है, 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(वे स्पष्ट रूप से स्थिर हैं)
  • निरंतर समय पर मूल्य का मूल्यांकन किया जाता है
  • स्थिरांक केवल घोषणा में आरम्भिक हैं

सिफ़ पढ़िये

  • वे या तो उदाहरण-स्तर या स्थिर हो सकते हैं
  • मान का मूल्यांकन रन टाइम पर किया जाता है
  • घोषणा में या कंस्ट्रक्टर में कोड द्वारा आसानी से आरम्भ किया जा सकता है

6
वे स्थिर नहीं हो सकते , वे स्थिर हैं। आपको यह स्पष्ट करना चाहिए कि अगर आपका मतलब है कि कोई घोषित नहीं कर सकता हैstatic const int i = 0;
nawfal

क्या आप बता सकते हैं कि constघोषणाएँ विधियों के अंदर क्यों नहीं की जा सकतीं?
मिन्ह ट्रान

21

एक कॉन्सल एक संकलन-समय स्थिर है, जबकि आसानी से रन-टाइम पर एक वैल्यू की गणना की जाती है और कंस्ट्रक्टर या फील्ड एडवाइजर में सेट की जाती है। इसलिए, एक 'कॉन्स्टेंट' हमेशा स्थिर होता है लेकिन 'रीडऑनली' केवल एक बार पढ़ा जाता है।

C # टीम के एरिक लिपर्ट के पास विभिन्न प्रकार की अपरिवर्तनीयता के बारे में अधिक जानकारी है


15

यह दिखाने के लिए कि लिंक कैसे सुरक्षित नहीं है, या संदर्भ प्रकारों के लिए प्रासंगिक एक और लिंक यहां दिया गया है

सारांश :

  • आपकी कास्ट प्रॉपर्टी का मूल्य संकलन समय पर सेट किया गया है और रनटाइम में नहीं बदल सकता है
  • कॉन्स्ट को स्थिर के रूप में चिह्नित नहीं किया जा सकता है - कीवर्ड का अर्थ है कि वे स्थिर हैं, आसानी से फ़ील्ड के विपरीत जो कर सकते हैं।
  • मूल्य (आदिम) प्रकारों को छोड़कर कास्ट कुछ भी नहीं हो सकता है
  • पठनीय कीवर्ड फ़ील्ड को अपरिवर्तनीय के रूप में चिह्नित करता है। हालांकि संपत्ति को क्लास के कंस्ट्रक्टर के अंदर बदला जा सकता है
  • रीडऑनली केवल कीवर्ड को स्थैतिक के साथ जोड़ा जा सकता है ताकि इसे उसी तरह से काम किया जा सके जैसे कि एक कॉस्ट (सतह पर कम से कम)। जब आप दोनों के बीच आईएल को देखते हैं तो एक उल्लेखनीय अंतर होता है
  • कास्ट फ़ील्ड्स को IL में "शाब्दिक" के रूप में चिह्नित किया जाता है, जबकि आसानी से "initonly"

11

Read Only : रनटाइम के समय Ctor के माध्यम से मूल्य को बदला जा सकता है लेकिन मेंबर फंक्शन के जरिए नहीं

लगातार : स्थिर द्वारा रक्षा। मान को कहीं से भी नहीं बदला जा सकता (Ctor, Function, runtime etc no-जहाँ)


मुझे इन दो टेक-वे के लिए सिर्फ 4 पैराग्राफ पढ़ने के लिए नहीं बनाने के लिए धन्यवाद ...
डॉन चेडल

9

अभी तक एक और गोटा: प्रतिबिंब के माध्यम से "कुटिल" कोड द्वारा आसानी से मूल्यों को बदला जा सकता है।

var fi = this.GetType()
             .BaseType
             .GetField("_someField", 
                       BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);

क्या मैं प्रतिबिंब का उपयोग करके C # में एक निजी पठनीय विरासत में मिला क्षेत्र बदल सकता हूँ?


6

मेरा मानना constहै कि सभी वस्तुओं के लिए एक मूल्य समान है (और इसे शाब्दिक अभिव्यक्ति के साथ आरंभ किया जाना चाहिए), जबकि readonlyप्रत्येक तात्कालिक के लिए अलग हो सकता है ...


5

हमारे कार्यालय में टीम के सदस्यों में से एक ने कॉन्स्टेबल, स्टेटिक और आसानी से उपयोग करने के बारे में निम्नलिखित मार्गदर्शन प्रदान किया:

  • उपयोग स्थिरांक आप एक प्रकार का एक चर आप कार्यावधि में पता कर सकते हैं (स्ट्रिंग शाब्दिक, पूर्णांक, डबल, enums, ...) है कि आप का उपयोग करने की सभी आवृत्तियों या एक वर्ग के उपभोक्ताओं चाहते हैं जब जहां मूल्य परिवर्तन नहीं करना चाहिए।
  • स्थैतिक का उपयोग करें जब आपके पास वह डेटा हो जो आप चाहते हैं कि किसी वर्ग के सभी उदाहरण या उपभोक्ता जहां पहुंच बदल सकें, जहां मूल्य बदल सकता है।
  • स्थैतिक का प्रयोग तब करें जब आपके पास एक प्रकार का चर हो जिसे आप रनटाइम (ऑब्जेक्ट्स) में नहीं जान सकते हैं कि आप एक वर्ग के सभी उदाहरण या उपभोक्ता चाहते हैं कि मूल्य में परिवर्तन नहीं होना चाहिए।
  • का प्रयोग करें केवल पढ़ने के लिए आप एक उदाहरण स्तर चर आप ऑब्जेक्ट निर्माण कि परिवर्तन नहीं होना चाहिए के समय में पता चल जाएगा जब।

एक अंतिम नोट: एक कास्ट फील्ड स्थिर है, लेकिन व्युत्क्रम सत्य नहीं है।


1
मुझे लगता है कि आपका मतलब है "समझाना।" व्युत्क्रम "एक गैर-कॉन्स्टल फ़ील्ड स्थिर नहीं है।" जो सच हो या न हो। ऐंठन, "एक स्थिर क्षेत्र है (हमेशा) कास्ट" सच नहीं है।
माइकल ब्लैकबर्न

5

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

उदाहरण:

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; }
  }
}

5
  • कब उपयोग करें constयाreadonly

    • const

      • संकलन-समय स्थिर: निरपेक्ष स्थिर, मूल्य घोषणा के दौरान निर्धारित किया जाता है, IL कोड में ही होता है
    • readonly

      • रन-टाइम स्थिर: कन्स्ट्रक्टर / इनिट में कॉन्फिगर फाइल के माध्यम से सेट किया जा सकता है App.config, लेकिन एक बार इसे शुरू करने के बाद इसे बदला नहीं जा सकता है

4

वैरिएबल चिह्नित कॉस्ट दृढ़ता से टाइप किए गए #define मैक्रोज़ से थोड़ा अधिक हैं, संकलन समय पर कॉन्सल चर संदर्भों को इनलाइन शाब्दिक मानों के साथ बदल दिया जाता है। एक परिणाम के रूप में केवल कुछ अंतर्निर्मित आदिम मूल्य प्रकार इस तरह से उपयोग किए जा सकते हैं। आसानी से चिह्नित वेरिएबल्स को एक कंस्ट्रक्टर में, रन-टाइम पर सेट किया जा सकता है और रन-टाइम के दौरान उनका रीड-ओनली-नेस लागू किया जाता है। इससे जुड़ी कुछ मामूली प्रदर्शन लागत है लेकिन इसका मतलब है कि आप किसी भी प्रकार (यहां तक ​​कि संदर्भ प्रकार) के साथ आसानी से उपयोग कर सकते हैं।

इसके अलावा, कांस्टेबल चर स्वाभाविक रूप से स्थिर होते हैं, जबकि वांछित होने पर पठनीय चर विशिष्ट हो सकते हैं।


जोड़ा गया है कि कॉन्स्टेंस दृढ़ता से #define मैक्रोज़ टाइप किए गए हैं। अन्यथा, हम सभी C या C ++ लोगों को डरा सकते हैं। :-)
जेसन बेकर

4

CONST

  1. const कीवर्ड फ़ील्ड या स्थानीय चर पर लागू किया जा सकता है
  2. हमें घोषणा के समय कॉन्स्ट फील्ड असाइन करना चाहिए
  3. संकलित होने के बाद कोई मेमोरी आवंटित नहीं की जाती क्योंकि IL मान कोड में ही समाहित है। यह कॉन्स्टेबल वैरिएबल की सभी घटनाओं को खोजने और उसके मूल्य के द्वारा प्रतिस्थापित करने जैसा है। इसलिए संकलन के बाद IL कोड में कॉन्स्टेबल वैरिएबल के स्थान पर हार्ड-कोडेड मान होंगे
  4. C # में कॉन्स्टेबल डिफ़ॉल्ट स्टैटिक हैं।
  5. सभी वस्तुओं के लिए मान स्थिर है
  6. Dll संस्करण मुद्दा है - इसका मतलब है कि जब भी हम किसी सार्वजनिक कास्ट वैरिएबल या प्रॉपर्टी को बदलते हैं, (वास्तव में, इसे सैद्धांतिक रूप से बदलना नहीं चाहिए), कोई भी अन्य dll या असेंबली जो इस वैरिएबल का उपयोग करती है, उसे फिर से बनाया जाना है।
  7. केवल C # अंतर्निहित प्रकारों को ही स्थिर घोषित किया जा सकता है
  8. कॉन्स्ट फ़ील्ड को रेफरी या आउट पैरामीटर के रूप में पारित नहीं किया जा सकता है

सिफ़ पढ़िये

  1. आसानी से कीवर्ड केवल उन क्षेत्रों पर लागू होता है जो स्थानीय चर नहीं हैं
  2. हम घोषणा के समय या कंस्ट्रक्टर में आसानी से किसी भी अन्य तरीकों से कार्य कर सकते हैं।
  3. डायनामिक मेमोरी को आसानी से खेतों के लिए आवंटित किया जाता है और हम रन समय पर मूल्य प्राप्त कर सकते हैं।
  4. कक्षा के केवल उदाहरण के माध्यम से इतनी आसानी से बनाई गई वस्तु के बारे में पढ़ें। इसे कक्षा का सदस्य बनाने के लिए हमें स्थैतिक कीवर्ड को आसानी से पढ़ने से पहले जोड़ना होगा।
  5. उपयोग किए गए कंस्ट्रक्टर के आधार पर मूल्य भिन्न हो सकता है (क्योंकि यह वर्ग का उद्देश्य है)
  6. यदि आप एक गैर-आदिम प्रकार (संदर्भ प्रकार) की घोषणा करते हैं, तो केवल संदर्भ के रूप में केवल संदर्भ अपरिवर्तनीय है, जिसमें वह वस्तु नहीं है।
  7. चूँकि मान रन टाइम पर प्राप्त होता है, इसलिए रीडऑनली फ़ील्ड्स / प्रॉपर्टीज़ के साथ डीएल वर्जनिंग समस्या नहीं होती है।
  8. हम निर्माता के संदर्भ में मापदंडों के रूप में आसानी से या पार कर सकते हैं।

3

एक और गच्चा

चूंकि कॉन्स्ट वास्तव में केवल बुनियादी डेटा प्रकारों के साथ काम करता है, यदि आप एक वर्ग के साथ काम करना चाहते हैं, तो आप ReadOnly का उपयोग करने के लिए "मजबूर" महसूस कर सकते हैं। हालाँकि, जाल से सावधान रहें! ReadOnly का अर्थ है कि आप ऑब्जेक्ट को किसी अन्य ऑब्जेक्ट से बदल नहीं सकते (आप इसे किसी अन्य ऑब्जेक्ट को संदर्भित नहीं कर सकते)। लेकिन किसी भी प्रक्रिया में ऑब्जेक्ट के संदर्भ में ऑब्जेक्ट के अंदर मूल्यों को संशोधित करने के लिए स्वतंत्र है !

इसलिए यह सोचकर भ्रमित न हों कि ReadOnly का तात्पर्य है कि उपयोगकर्ता चीजों को बदल नहीं सकता है। किसी वर्ग की तात्कालिकता को उसके आंतरिक मूल्यों को बदलने से रोकने के लिए सी # में कोई सरल वाक्यविन्यास नहीं है (जहाँ तक मुझे पता है)।


हाँ जो एक सामान्य विषय से अधिक है। यदि आपके पास केवल एक सरणी सूची को उजागर करने वाली संपत्ति है, तो आप अभी भी सरणी सूची को संशोधित कर सकते हैं। आप उस प्रॉपर्टी के लिए एक अलग सरणी सूची सेट नहीं कर सकते हैं, लेकिन आप उपयोगकर्ता को सरणी सूची में फेरबदल करने से नहीं रोक सकते।
गिशु

3

constको हार्ड-कोडेड होना चाहिए , जहां क्लास के कंस्ट्रक्टर में सेट किया readonlyजा सकता है ।


3

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 का उपयोग करना संभव नहीं है।


2

एक स्थिर को उपभोक्ता में शाब्दिक मूल्य के रूप में संकलित किया जाएगा जबकि स्थिर स्ट्रिंग परिभाषित मूल्य के संदर्भ के रूप में काम करेगा।

एक अभ्यास के रूप में, एक बाहरी पुस्तकालय बनाने की कोशिश करें और इसे एक कंसोल एप्लिकेशन में उपभोग करें, फिर लाइब्रेरी में मूल्यों को बदल दें और इसे फिर से जोड़ें (उपभोक्ता कार्यक्रम को फिर से शुरू किए बिना), DLL को निर्देशिका में छोड़ दें और मैन्युअल रूप से EXE चलाएं, आपको मिलना चाहिए निरंतर स्ट्रिंग परिवर्तित नहीं होती है।


मुझे पूरी तरह से संदेह है कि यह सच है ... मैं जाँच करूँगा।
ljs

यह आपके C # को बेहतर बनाने के 50 विशिष्ट तरीकों में से एक है - amazon.co.uk/Effective-Specific-Ways-Improve-Your/dp/0321245660/…
Russ Cam


@ और हरे - हाँ, मैंने अभी जाँच की है। मैं बहुत आश्चर्यचकित हूं, यह एक वास्तविक गेटा है, मैं वास्तव में बहुत आश्चर्यचकित हूं, यह आश्चर्यचकित है कि ...!
ljs

हालाँकि, मैं यहाँ सूचक शब्द के उपयोग पर आपत्ति करता हूँ। यह एक सूचक नहीं है, यह एक संदर्भ है, और वहाँ है के रूप में आप असुरक्षित मोड में अप्रबंधित संकेत हेरफेर कर सकते हैं तो यह दोनों के बीच अंतर करने के लिए महत्वपूर्ण है सी # में एक फर्क।
ljs

2

लगातार

जब परिभाषित किया जाता है तो हमें कॉस्ट फ़ील्ड को मान प्रदान करना होगा। संकलक तब असेंबली के मेटाडेटा में निरंतर मान बचाता है। इसका मतलब यह है कि एक स्थिरांक को केवल आदिम प्रकार जैसे कि बूलियन, चार, बाइट और इसी तरह के लिए परिभाषित किया जा सकता है। स्थिरांक हमेशा स्थिर सदस्य माने जाते हैं, उदाहरण के सदस्य नहीं।

सिफ़ पढ़िये

केवल पठनीय क्षेत्रों को रनटाइम पर हल किया जा सकता है। इसका मतलब है कि हम उस प्रकार के लिए कंस्ट्रक्टर का उपयोग करके एक मान को परिभाषित कर सकते हैं जिसमें फ़ील्ड घोषित किया गया है। सत्यापन कम्पाइलर द्वारा किया जाता है कि आसानी से खेतों को कंस्ट्रक्टर के अलावा किसी अन्य विधि से नहीं लिखा जाता है।

दोनों के बारे में अधिक इस लेख में यहाँ बताया गया है


1

मुख्यतः; आप एक स्थिर स्थैतिक क्षेत्र के लिए एक मान को रनटाइम पर एक गैर-स्थिर मान पर असाइन कर सकते हैं, जबकि एक कॉन्स्ट को एक स्थिर मान सौंपा जाना है।


1

कॉन्स्ट और पठनीय समान हैं, लेकिन वे बिल्कुल समान नहीं हैं। एक कास्ट फ़ील्ड एक संकलन-समय स्थिर है, जिसका अर्थ है कि संकलन-समय पर उस मूल्य की गणना की जा सकती है। एक पठनीय क्षेत्र अतिरिक्त परिदृश्यों को सक्षम करता है जिसमें प्रकार के निर्माण के दौरान कुछ कोड चलाने चाहिए। निर्माण के बाद, आसानी से एक फ़ील्ड नहीं बदला जा सकता है।

उदाहरण के लिए, कास्ट मेंबर का इस्तेमाल सदस्यों को परिभाषित करने के लिए किया जा सकता है:

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 हमेशा शून्य रहेगा। दोनों कांस्टेबल का उपयोग और आसानी से ए के डेवलपर को इरादा निर्दिष्ट करने की अनुमति देता है। यह बेहतर संस्करण व्यवहार और बेहतर प्रदर्शन के लिए बनाता है।


1

ReadOnly: मूल्य केवल वर्ग के निर्माता से एक बार आरंभ किया जाएगा।
const: किसी भी फंक्शन में इनिशियलाइज़ किया जा सकता है लेकिन केवल एक बार


1

अंतर यह है कि एक स्थिर पठनीय क्षेत्र का मान रन टाइम पर सेट किया जाता है, इसलिए इसमें प्रोग्राम के विभिन्न निष्पादन के लिए एक अलग मूल्य हो सकता है। हालाँकि, एक कास्ट फ़ील्ड का मान एक स्थिर समय स्थिर करने के लिए सेट किया गया है।

याद रखें: संदर्भ प्रकारों के लिए, दोनों मामलों में (स्थिर और उदाहरण), केवल पढ़ने योग्य संशोधक आपको फ़ील्ड के लिए एक नया संदर्भ निर्दिष्ट करने से रोकता है। यह विशेष रूप से संदर्भ द्वारा इंगित वस्तु को अपरिवर्तनीय नहीं बनाता है।

जानकारी के लिए, कृपया इस विषय पर C # अक्सर पूछे जाने वाले प्रश्न देखें: http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx


1

लगातार चर घोषित किए जाते हैं और संकलन समय पर शुरू हो जाते हैं। वार्ड के बाद मान को बदला नहीं जा सकता। रीड-ओनली वेरिएबल को केवल क्लास के स्टैटिक कंस्ट्रक्टर से इनिशियलाइज़ किया जाएगा। केवल तभी उपयोग किया जाता है जब हम रन टाइम पर मान असाइन करना चाहते हैं।


1

कास्ट : आवेदन जीवन समय के दौरान पूर्ण स्थिर मूल्य।

Readonly : इसे रनिंग टाइम में बदला जा सकता है।


1
'Readonly' की आपकी परिभाषा कि यह बदल सकता है त्रुटिपूर्ण है। मुझे लगता है कि 'परिवर्तन' से आपका मतलब 'सेट' है, जैसे 'इसे रनटाइम पर सेट किया जा सकता है'।
अहमद

0

एक बात जो लोगों ने ऊपर कही है उसे जोड़ने के लिए। यदि आपके पास एक असेंबली है जिसमें रीडॉनली वैल्यू है (उदाहरण के लिए MaxFooCount = 4;), तो आप उस असेंबली को एक अलग मूल्य के साथ उस असेंबली के नए संस्करण को शिपिंग करके देख सकने वाले मान को बदल सकते हैं (उदाहरण के लिए MaxFooCount = 5;)।

लेकिन एक कास्ट के साथ, यह कॉलर के कोड में बदल जाएगा जब कॉलर संकलित किया गया था।

यदि आप C # प्रवीणता के इस स्तर पर पहुँच गए हैं, तो आप Bill Wagner की पुस्तक के लिए तैयार हैं, प्रभावी C #: 50 आपके C को बेहतर बनाने के विशिष्ट तरीके # जो इस प्रश्न का उत्तर विस्तार से देते हैं, (और 49 अन्य बातों का)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.