c# - एक क्षेत्र और संपत्ति के बीच क्या अंतर है?




बाजार मूल्य की परिभाषा (20)

अंतर - उपयोग (कब और क्यों)

एक फ़ील्ड एक चर है जिसे सीधे कक्षा या संरचना में घोषित किया जाता है। एक वर्ग या संरचना में उदाहरण फ़ील्ड या स्थिर फ़ील्ड या दोनों हो सकते हैं। आम तौर पर, आपको केवल उन चर के लिए फ़ील्ड्स का उपयोग करना चाहिए जिनके पास निजी या संरक्षित पहुंच है । क्लाइंट कोड के लिए आपकी कक्षा का खुलासा करने वाला डेटा विधियों, गुणों और अनुक्रमणकों के माध्यम से प्रदान किया जाना चाहिए । आंतरिक क्षेत्रों में अप्रत्यक्ष पहुंच के लिए इन संरचनाओं का उपयोग करके, आप अमान्य इनपुट मानों के खिलाफ सुरक्षा कर सकते हैं।

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

सी # में, किसी संपत्ति से किसी फ़ील्ड को अलग करता है, और किसी संपत्ति के बजाय फ़ील्ड का उपयोग कब किया जाना चाहिए?


(यह वास्तव में एक टिप्पणी होनी चाहिए, लेकिन मैं कोई टिप्पणी पोस्ट नहीं कर सकता, इसलिए क्षमा करें अगर यह एक पोस्ट के रूप में उपयुक्त नहीं है)।

मैंने एक बार ऐसी जगह पर काम किया जहां अनुशंसित अभ्यास संपत्तियों के बजाय सार्वजनिक क्षेत्रों का उपयोग करना था जब समकक्ष संपत्ति डीफ़ सिर्फ एक क्षेत्र तक पहुंच रहा होगा, जैसा कि:

get { return _afield; }
set { _afield = value; }

उनका तर्क यह था कि यदि आवश्यक हो तो सार्वजनिक क्षेत्र को बाद में भविष्य में एक संपत्ति में परिवर्तित किया जा सकता है। उस समय मेरे लिए थोड़ा अजीब लग रहा था। इन पदों के आधार पर, ऐसा लगता है कि यहां पर कई लोग सहमत नहीं होंगे। चीजों को बदलने की कोशिश करने के लिए आपने क्या कहा होगा?

संपादित करें: मुझे यह जोड़ना चाहिए कि इस स्थान पर सभी कोड बेस एक ही समय में संकलित किए गए थे, इसलिए उन्होंने सोचा होगा कि कक्षाओं के सार्वजनिक इंटरफेस को बदलना (किसी संपत्ति में सार्वजनिक क्षेत्र बदलकर) कोई समस्या नहीं थी।


एक क्षेत्र का मेरा डिजाइन यह है कि एक फ़ील्ड को केवल अपने माता-पिता, इसलिए कक्षा द्वारा संशोधित करने की आवश्यकता है। Result the variable becomes private, then to be able to give the right to read the classes / methods outside I go through the system of property with only the Get. The field is then retrieved by the property and read-only! If you want to modify it you have to go through methods (for example the constructor) and I find that thanks to this way of making you secure, we have better control over our code because we "flange". One could very well always put everything in public so every possible case, the notion of variables / methods / classes etc ... in my opinion is just an aid to the development, maintenance of the code. For example, if a person resumes a code with public fields, he can do anything and therefore things "illogical" in relation to the objective, the logic of why the code was written. It's my point of view.

When i use a classic model private field / public readonly properties,for 10 privates fields i should write 10 publics properties! The code can be really big faster. I discover the private setter and now i only use public properties with a private setter. The setter create in background a private field.

That why my old classic programming style was:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

My new programming style:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}

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


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

public class Person
{
   private string _name;

   public string Name
   {
      get
      {
         return _name;
      }
      set
      {
         _name = value;
      }
   }
   public int Age{get;set;} //AutoProperty generates private field for us
}

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

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

फ़ील्ड का उपयोग आउट / रेफ पैरामीटर के लिए किया जा सकता है, गुण नहीं हो सकते हैं। गुण अतिरिक्त तर्क का समर्थन करते हैं - इसका उपयोग अन्य चीजों के बीच आलसी लोडिंग को लागू करने के लिए किया जा सकता है।

गुण मूल्य प्राप्त करने / सेट करने के लिए जो भी मतलब है उसे encapsulating द्वारा abstraction के एक स्तर का समर्थन करते हैं।

अधिकांश / सभी मामलों में गुणों का उपयोग करें, लेकिन दुष्प्रभावों से बचने का प्रयास करें।


गुण फ़ील्ड को समाहित करते हैं, इस प्रकार आपको सेट या पुनर्प्राप्त करने के लिए मूल्य पर अतिरिक्त प्रसंस्करण करने में सक्षम बनाता है। यह आमतौर पर गुणों का उपयोग करने के लिए अधिक है यदि आप फ़ील्ड मान पर कोई पूर्व-या पोस्टप्रोकैसिंग नहीं कर रहे हैं।


गुण विशेष प्रकार के वर्ग सदस्य हैं, गुणों में हम एक पूर्वनिर्धारित सेट या विधि प्राप्त करते हैं। वे एक्सेसर्स का उपयोग करते हैं जिसके माध्यम से हम निजी क्षेत्रों के मूल्यों को पढ़, लिखे या बदल सकते हैं।

उदाहरण के लिए, आइए नाम, आयु और कर्मचारी_आईडी के लिए निजी फ़ील्ड के साथ Employee नामक कक्षा लें। हम कक्षा के बाहर से इन क्षेत्रों तक नहीं पहुंच सकते हैं, लेकिन हम इन निजी क्षेत्रों को संपत्तियों के माध्यम से एक्सेस कर सकते हैं।

हम गुणों का उपयोग क्यों करते हैं?

कक्षा क्षेत्र को सार्वजनिक बनाना और इसे उजागर करना जोखिम भरा है, क्योंकि आपके पास नियंत्रण नहीं होगा जो आवंटित और लौटाया जाता है।

उदाहरण के साथ इसे स्पष्ट रूप से समझने के लिए एक छात्र वर्ग लें जिसमें आईडी, पासमार्क, नाम हो। अब इस क्षेत्र में सार्वजनिक क्षेत्र के साथ कुछ समस्या है

  • आईडी नहीं होना चाहिए।
  • नाम शून्य पर सेट नहीं किया जा सकता है
  • पास मार्क केवल पढ़ा जाना चाहिए।
  • यदि छात्र का नाम गुम है तो कोई नाम वापस नहीं होना चाहिए।

इस समस्या को हटाने के लिए हम विधि प्राप्त करें और सेट करें।

// A simple example
public class student
{
    public int ID;
    public int passmark;
    public string name;
}

public class Program
{
    public static void Main(string[] args)
    {
       student s1 = new student();
       s1.ID = -101; // here ID can't be -ve
       s1.Name = null ; // here Name can't be null
    }
}

अब हम प्राप्त करने और सेट विधि का एक उदाहरण लेते हैं

public class student
{
    private int _ID;
    private int _passmark;
    private string_name ;
    // for id property
    public void SetID(int ID)
    {
        if(ID<=0)
        {
            throw new exception("student ID should be greater then 0");
        }
        this._ID = ID;
    }
    public int getID()
    {
        return_ID;
    }
}
public class programme
{
    public static void main()
    {
        student s1 = new student ();
        s1.SetID(101);
    }
    // Like this we also can use for Name property
    public void SetName(string Name)
    {
        if(string.IsNullOrEmpty(Name))
        {
            throw new exeception("name can not be null");
        }
        this._Name = Name;
    }
    public string GetName()
    {
        if( string.IsNullOrEmpty(This.Name))
        {
            return "No Name";
        }
        else
        {
            return this._name;
        }
    }
        // Like this we also can use for Passmark property
    public int Getpassmark()
    {
        return this._passmark;
    }
}

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

यदि आप विस्तृत खपत के लिए डिज़ाइन की गई क्लास लाइब्रेरी लिखते हैं (जैसे .NET Framework, जिसका उपयोग लाखों लोगों द्वारा किया जाता है), यह एक समस्या हो सकती है। हालांकि, अगर आप एक छोटे कोड बेस (<= 50 के लाइनों) के अंदर आंतरिक रूप से उपयोग की जाने वाली कक्षा लिख ​​रहे हैं, तो यह वास्तव में एक बड़ा सौदा नहीं है, क्योंकि आपके परिवर्तनों से कोई भी प्रतिकूल रूप से प्रभावित नहीं होगा। उस स्थिति में यह वास्तव में व्यक्तिगत वरीयता के लिए आता है।


चूंकि उनमें से कई ने तकनीकी पेशेवरों और Properties और Field विपक्ष के साथ समझाया है, अब वास्तविक समय के उदाहरणों में शामिल होने का समय है।

1. गुण आपको केवल पढ़ने के लिए पहुंच स्तर सेट करने की अनुमति देता है

dataTable.Columns[i].Caption और dataTable.Columns[i].Caption के मामले पर विचार करें। dataTable.Columns[i].Caption । वे कक्षा DataTable से आते हैं और दोनों हमारे लिए सार्वजनिक हैं। उनके लिए पहुंच-स्तर में अंतर यह है कि हम dataTable.Columns[i].Caption नहीं कर सकते हैं। dataTable.Columns[i].Caption लेकिन हम dataTable.Columns[i].Caption को पढ़ और लिख सकते हैं। dataTable.Columns[i].CaptiondataTable.Columns[i].CaptiondataTable.Columns[i].Caption । क्या यह Field माध्यम से संभव है? नहीं!!! यह केवल Properties साथ किया जा सकता है।

public class DataTable
{
    public class Rows
    {       
       private string _count;        

       // This Count will be accessable to us but have used only "get" ie, readonly
       public int Count
       {
           get
           {
              return _count;
           }       
       }
    } 

    public class Columns
    {
        private string _caption;        

        // Used both "get" and "set" ie, readable and writable
        public string Caption
        {
           get
           {
              return _caption;
           }
           set
           {
              _caption = value;
           }
       }       
    } 
}

2. संपत्ति ग्रिड में गुण

आपने विजुअल स्टूडियो में Button साथ काम किया होगा। इसके गुण PropertyGrid में Text , Name इत्यादि जैसे दिखाए जाते हैं। जब हम बटन खींचते हैं और छोड़ते हैं, और जब हम गुणों पर क्लिक करते हैं, तो यह स्वचालित रूप से क्लास Button और फ़िल्टर Properties को पाता है और यह दिखाता है कि PropertyGrid (जहां PropertyGrid नहीं दिखाएगा Field भले ही वे सार्वजनिक हैं)।

public class Button
{
    private string _text;        
    private string _name;
    private string _someProperty;

    public string Text
    {
        get
        {
           return _text;
        }
        set
        {
           _text = value;
        }
   } 

   public string Name
   {
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   } 

   [Browsable(false)]
   public string SomeProperty
   {
        get
        {
           return _someProperty;
        }
        set
        {
           _someProperty= value;
        }
   } 

PropertyGrid , गुणों का Name और Text दिखाया जाएगा, लेकिन कुछ PropertyGrid नहीं। क्यूं कर??? क्योंकि गुण गुण स्वीकार कर सकते हैं। यह उस स्थिति में नहीं दिखाया गया है जहां [Browsable(false)] गलत है।

3. गुणों के अंदर बयान निष्पादित कर सकते हैं

public class Rows
{       
    private string _count;        


    public int Count
    {
        get
        {
           return CalculateNoOfRows();
        }  
    } 

    public int CalculateNoOfRows()
    {
         // Calculation here and finally set the value to _count
         return _count;
    }
}

4. बाध्यकारी स्रोत में केवल गुणों का उपयोग किया जा सकता है

बाध्यकारी स्रोत हमें कोड की रेखाओं की संख्या को कम करने में मदद करता है। BindingSource द्वारा Fields स्वीकार नहीं किए जाते हैं। हमें इसके लिए Properties उपयोग करना चाहिए।

5. डिबगिंग मोड

विचार करें कि हम मूल्य रखने के लिए Field का उपयोग कर रहे हैं। किसी बिंदु पर हमें डीबग करने और जांचने की आवश्यकता है कि उस क्षेत्र के लिए मूल्य कहाँ शून्य हो रहा है। ऐसा करना मुश्किल होगा जहां कोड की लाइनों की संख्या 1000 से अधिक हो। ऐसी परिस्थितियों में हम Property उपयोग कर सकते हैं और Property अंदर डीबग मोड सेट कर सकते हैं।

   public string Name
   {
        // Can set debug mode inside get or set
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   }

जब आपके पास एक वर्ग है जो "कार" है। गुण रंग, आकार हैं ..

जहां फ़ील्ड एक वर्ग के दायरे में परिभाषित चर हैं।


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


परंपरागत रूप से निजी क्षेत्र गेटटर और सेटर विधियों के माध्यम से सेट होते हैं। कम कोड के लिए आप इसके बजाय फ़ील्ड सेट करने के लिए गुणों का उपयोग कर सकते हैं।


पृष्ठभूमि में एक संपत्ति विधियों में संकलित है। तो एक Name संपत्ति get_Name() और set_Name(string value) में संकलित की जाती है। यदि आप संकलित कोड का अध्ययन करते हैं तो आप इसे देख सकते हैं। तो उनका उपयोग करते समय एक (बहुत) छोटा प्रदर्शन ओवरहेड होता है। आम तौर पर यदि आप बाहर के क्षेत्र का पर्दाफाश करते हैं तो आप हमेशा संपत्ति का उपयोग करेंगे, और यदि आप मूल्य की पुष्टि करने की आवश्यकता है तो आप अक्सर इसे आंतरिक रूप से उपयोग करेंगे।


मैं आपको उन गुणों का उपयोग करने के कुछ उदाहरण दूंगा जो गियर मोड़ सकते हैं:

  • आलसी शुरुआत : यदि आपके पास उस वस्तु की संपत्ति है जो लोड करने के लिए महंगा है, लेकिन कोड के सामान्य रनों में जितना अधिक उपयोग नहीं किया जाता है, तो आप संपत्ति के माध्यम से अपनी लोडिंग में देरी कर सकते हैं। इस तरह, यह बस वहां बैठा है, लेकिन पहली बार एक और मॉड्यूल उस संपत्ति को कॉल करने का प्रयास करता है, यह जांचता है कि अंतर्निहित क्षेत्र शून्य है - अगर ऐसा है, तो यह आगे बढ़ता है और इसे लोड करता है, कॉलिंग मॉड्यूल के लिए अज्ञात है। यह ऑब्जेक्ट प्रारंभिकता को बहुत तेज़ी से बढ़ा सकता है।
  • गंदा ट्रैकिंग: जो मैंने वास्तव में यहां अपने स्वयं के प्रश्न से स्टैक ओवरव्लो पर सीखा। जब मेरे पास बहुत सारी ऑब्जेक्ट्स होती हैं जो रन के दौरान मूल्य बदल सकते हैं, तो मैं संपत्ति को ट्रैक करने के लिए उपयोग कर सकता हूं कि उन्हें डेटाबेस में वापस सहेजने की आवश्यकता है या नहीं। यदि किसी ऑब्जेक्ट की एक ही संपत्ति नहीं बदली है, तो IsDirty ध्वज ट्रिप नहीं किया जाएगा, और इसलिए डेटाबेस पर वापस आने की आवश्यकता का निर्णय लेने पर बचत कार्यक्षमता इसे छोड़ देगी।

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


साथ ही, गुणों को सेट करते समय गुण आपको तर्क का उपयोग करने की अनुमति देते हैं।

तो आप कह सकते हैं कि आप केवल एक पूर्णांक फ़ील्ड में मान सेट करना चाहते हैं, यदि मान x से बड़ा है, अन्यथा अपवाद फेंक दें।

वास्तव में उपयोगी सुविधा।


Additional info: By default, get and set accessors are as accessible as the property itself. You can control/restrict accessor accessibility individually (for get and set) by applying more restrictive access modifiers on them.

उदाहरण:

public string Name
{
    get
    {
        return name;
    }
    protected set
    {
        name = value;
    }
}

Here get is still publicly accessed (as the property is public), but set is protected (a more restricted access specifier).


The vast majority of cases it's going to be a property name that you access as opposed to a variable name ( field ) The reason for that is it's considered good practice in .NET and in C# in particular to protect every piece of data within a class, whether it's an instance variable or a static variable (class variable) because it's associated with a class.

Protect all of those variables with corresponding properties which allow you to define, set and get accessors and do things like validation when you're manipulating those pieces of data.

But in other cases like Math class (System namespace), there are a couple of static properties that are built into the class. one of which is the math constant PI

जैसे। Math.PI

and because PI is a piece of data that is well-defined, we don't need to have multiple copies of PI, it always going to be the same value. So static variables are sometimes used to share data amongst object of a class, but the are also commonly used for constant information where you only need one copy of a piece of data.


Think about it : You have a room and a door to enter this room. If you want to check how who is coming in and secure your room, then you should use properties otherwise they won't be any door and every one easily come in w/o any regulation

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

People is getting in to sectionOne pretty easily, there wasn't any checking

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

Now you checked the person and know about whether he has something evil with him





field