c# - आप सी#ऑटो-प्रॉपर्टी को डिफ़ॉल्ट मान कैसे देते हैं?




automatic-properties (15)

आप सी # ऑटो-प्रॉपर्टी को डिफ़ॉल्ट मान कैसे देते हैं? मैं या तो कन्स्ट्रक्टर का उपयोग करता हूं, या पुराने वाक्यविन्यास पर वापस आ जाता हूं।

कन्स्ट्रक्टर का उपयोग करना:

class Person 
{
    public Person()
    {
        Name = "Default Name";
    }
    public string Name { get; set; }
}

सामान्य संपत्ति वाक्यविन्यास का उपयोग करना (डिफ़ॉल्ट मान के साथ)

private string name = "Default Name";
public string Name 
{
    get 
    {
        return name;
    }
    set
    {
        name = value;
    }
}

क्या कोई बेहतर तरीका है?


सी # 6.0 में यह एक हवा है!

संपत्ति घोषणा घोषणाओं में आप इसे Class घोषणा में ही कर सकते हैं।

public class Coordinate
{ 
    public int X { get; set; } = 34; // get or set auto-property with initializer

    public int Y { get; } = 89;      // read-only auto-property with initializer

    public int Z { get; }            // read-only auto-property with no initializer
                                     // so it has to be initialized from constructor    

    public Coordinate()              // .ctor()
    {
        Z = 42;
    }
}

1/2/15 संपादित करें

सी # 6 के साथ आप ऑटो-प्रॉपर्टीज को सीधे शुरू कर सकते हैं (आखिरकार!), अब उस धागे में अन्य उत्तर हैं जो इसका वर्णन करते हैं।

सी # 5 और नीचे के लिए:

हालांकि विशेषता का इच्छित उपयोग वास्तव में गुणों के मान निर्धारित नहीं करना है, फिर भी आप हमेशा उन्हें सेट करने के लिए प्रतिबिंब का उपयोग कर सकते हैं ...

public class DefaultValuesTest
{    
    public DefaultValuesTest()
    {               
        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
        {
            DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];

            if (myAttribute != null)
            {
                property.SetValue(this, myAttribute.Value);
            }
        }
    }

    public void DoTest()
    {
        var db = DefaultValueBool;
        var ds = DefaultValueString;
        var di = DefaultValueInt;
    }


    [System.ComponentModel.DefaultValue(true)]
    public bool DefaultValueBool { get; set; }

    [System.ComponentModel.DefaultValue("Good")]
    public string DefaultValueString { get; set; }

    [System.ComponentModel.DefaultValue(27)]
    public int DefaultValueInt { get; set; }
}

उत्तर के अलावा पहले से ही स्वीकार्य है, परिदृश्य के लिए जब आप किसी अन्य प्रॉपर्टी के फ़ंक्शन के रूप में डिफ़ॉल्ट प्रॉपर्टी को परिभाषित करना चाहते हैं तो आप सी # 6.0 (और उच्चतर) पर अभिव्यक्ति बॉडी नोटेशन का उपयोग कर सकते हैं और यहां तक ​​कि अधिक सुरुचिपूर्ण और संक्षिप्त संरचनाओं के लिए:

public class Person{

    public string FullName  => $"{First} {Last}"; // expression body notation

    public string First { get; set; } = "First";
    public string Last { get; set; } = "Last";
}

आप उपरोक्त निम्नलिखित फैशन में उपयोग कर सकते हैं

    var p = new Person();

    p.FullName; // First Last

    p.First = "Jon";
    p.Last = "Snow";

    p.FullName; // Jon Snow

उपर्युक्त "=>" नोटेशन का उपयोग करने में सक्षम होने के लिए, संपत्ति केवल पढ़ी जानी चाहिए, और आप एक्सेस एक्सेसर कीवर्ड का उपयोग नहीं करते हैं।

MSDN पर विवरण


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


क्या आपने डिफॉल्ट वैल्यूएट्रिब्यूट या कन्फेशियललाइज और कन्स्ट्रक्टर के संयोजन के साथ तरीकों को रीसेट करने का प्रयास किया है? मुझे लगता है कि इन दो तरीकों में से एक आवश्यक है यदि आप ऐसी कक्षा बना रहे हैं जो डिजाइनर सतह पर या संपत्ति ग्रिड में दिखाई दे।


जब आप एक चर के लिए प्रारंभिक मान को रेखांकित करते हैं तो यह कन्स्ट्रक्टर में वैसे भी किया जाएगा।

मैं तर्क दूंगा कि यह वाक्यविन्यास सी # से 5 तक का सबसे अच्छा अभ्यास था:

class Person 
{
    public Person()
    {
        //do anything before variable assignment

        //assign initial values
        Name = "Default Name";

        //do anything after variable assignment
    }
    public string Name { get; set; }
}

चूंकि यह आपको ऑर्डर मानों का स्पष्ट नियंत्रण देता है।

सी # 6 के रूप में एक नया तरीका है:

public string Name { get; set; } = "Default Name"

थोड़ा पूरा नमूना:

using System.ComponentModel;

private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
    get { return bShowGroup; }
    set { bShowGroup = value; }
}

निजी तौर पर, यदि आप ऑटो-प्रॉपर्टी से परे कुछ भी नहीं करने जा रहे हैं तो मुझे इसे एक संपत्ति बनाने का मुद्दा नहीं दिख रहा है। बस इसे एक क्षेत्र के रूप में छोड़ दें। इन मदों के लिए encapsulation लाभ सिर्फ लाल बालियां हैं, क्योंकि उनके पीछे encapsulate करने के लिए कुछ भी नहीं है। यदि आपको कभी भी अंतर्निहित कार्यान्वयन को बदलने की आवश्यकता है तो आप किसी भी आश्रित कोड को तोड़ने के बिना उन्हें संपत्ति के रूप में पुन: सक्रिय करने के लिए स्वतंत्र हैं।

हम्म ... शायद यह बाद में अपने स्वयं के प्रश्न का विषय होगा


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


मुझे लगता है कि यह कुछ लोगों को झूठ बोलने के लिए कुछ करेगा।

private bool _SomeFlagSet = false;
public bool SomeFlag
{
    get
    {
        if (!_SomeFlagSet)
            SomeFlag = false;        

        return SomeFlag;
    }
    set
    {
        if (!_SomeFlagSet)
            _SomeFlagSet = true;

        SomeFlag = value;        
    }
}

सी # 5 और इससे पहले, ऑटो कार्यान्वित गुणों को एक डिफ़ॉल्ट मान देने के लिए, आपको इसे एक निर्माता में करना होगा।

ऑटो संपत्ति प्रारंभकर्ताओं की क्षमता सी # 6.0 के बाद शामिल है। वाक्यविन्यास है:

public int X { get; set; } = x; // C# 6 or higher

सी # 6 और ऊपर में आप सिंटैक्स का उपयोग कर सकते हैं:

public object Foo { get; set; } = bar;

ध्यान दें कि एक readonly संपत्ति रखने के लिए बस सेट को छोड़ दें, जैसा कि:

public object Foo { get; } = bar;

आप कन्स्ट्रक्टर से readonly ऑटो-गुण भी असाइन कर सकते हैं।

इससे पहले मैंने नीचे जवाब दिया।

मैं निर्माता को डिफ़ॉल्ट जोड़ने से बचना चाहता हूं; गतिशील असाइनमेंट के लिए छोड़ दें और दो बिंदुओं से बचें जिन पर चर निर्दिष्ट किया गया है (यानी प्रकार डिफ़ॉल्ट और कन्स्ट्रक्टर में)। आमतौर पर मैं ऐसे मामलों में एक सामान्य संपत्ति लिखूंगा।

एक अन्य विकल्प यह है कि ASP.Net क्या करता है और किसी विशेषता के माध्यम से डिफ़ॉल्ट को परिभाषित करता है:

http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx


सी # (6.0) और अधिक के संस्करण में, आप कर सकते हैं:

रीडोनली गुणों के लिए

public int ReadOnlyProp => 2;

लिखने योग्य और पठनीय गुण दोनों के लिए

public string PropTest { get; set; } = "test";

सी # (7.0) के वर्तमान संस्करण में, आप यह कर सकते हैं: (स्निपेट बल्कि यह दिखाता है कि बैकिंग फ़ील्ड के साथ उपयोग करते समय अभिव्यक्ति प्राप्त करने वाले / सेट एक्सेसर्स का उपयोग करने के लिए आप अधिक कॉम्पैक्ट कैसे बना सकते हैं)

private string label = "Default Value";

// Expression-bodied get / set accessors.
public string Label
{
   get => label;
   set => this.label = value; 
 }

सी # 6.0 से शुरू , हम स्वत: कार्यान्वित गुणों के लिए डिफ़ॉल्ट मान असाइन कर सकते हैं।

public string Name { get; set; } = "Some Name";

हम केवल पढ़ने योग्य ऑटो लागू संपत्ति भी बना सकते हैं जैसे:

public string Name { get; } = "Some Name";

देखें: सी # 6: पहली प्रतिक्रियाएं, स्वचालित रूप से कार्यान्वित गुणों के लिए प्रारंभकर्ता - जॉन स्कीट द्वारा


public Class ClassName{
    public int PropName{get;set;}
    public ClassName{
        PropName=0;  //Default Value
    }
}




automatic-properties