2008-10-03 11 views
160

मैं इस तरह की कक्षाओं लेखन करने के लिए इस्तेमाल कर रहा हूँ:प्रारंभ करने सी # ऑटो गुण

public class foo { 
    private string mBar = "bar"; 
    public string Bar { 
    get { return mBar; } 
    set { mBar = value; } 
    } 
    //... other methods, no constructor ... 
} 

एक स्वत: संपत्ति के लिए बार परिवर्तित सुविधाजनक और संक्षिप्त लगता है, लेकिन मैं कैसे एक निर्माता को जोड़ने और डाले बिना प्रारंभ बनाए रख सकते हैं वहां शुरूआत?

public class foo2theRevengeOfFoo { 
    //private string mBar = "bar"; 
    public string Bar { get; set; } 
    //... other methods, no constructor ... 
    //behavior has changed. 
} 

आप देख सकते हैं कि एक निर्माता जोड़ने प्रयास बचत मैं ऑटो गुणों से हो रही होना चाहिए कर रहा हूँ के अनुरूप नहीं है।

कुछ मुझसे इस तरह अधिक मतलब होगा:

public string Bar { get; set; } = "bar"; 
+1

क्या कोई विशेष कारण है कि आप इसे एक निर्माता में नहीं करना चाहते हैं क्योंकि यह मेरे लिए प्राकृतिक जगह है। –

+13

केवल इसलिए कि मुझे इसे पहले एक निर्माता में नहीं करना था। इसलिए अगर मुझे एक कन्स्ट्रक्टर जोड़ना है तो यह मुझे कोई प्रयास नहीं बचा रहा है। – dlamblin

+5

क्या होगा यदि यह स्टेटिक निजी स्ट्रिंग थे ...? फिर आप कन्स्ट्रक्टर के भीतर प्रवेश नहीं करना चाहते हैं क्योंकि हर बार एक नई वस्तु बनाई जाती है और यह विशेष रूप से नहीं चाहता था। ~~~ –

उत्तर

173

अद्यतन - सी # 6 के साथ आने से पहले नीचे दिया गया उत्तर लिखा गया था। सी # 6 में आप लिख सकते हैं:

public class Foo 
{ 
    public string Bar { get; set; } = "bar"; 
} 

आप कर सकते हैं भी बारे में केवल पढ़ने के लिए स्वचालित रूप से लागू गुण है, जो निर्माता में केवल लिखने योग्य हैं (लेकिन यह भी एक डिफ़ॉल्ट प्रारंभिक मूल्य दिया जा सकता है:

public class Foo 
{ 
    public string Bar { get; } 

    public Foo(string bar) 
    { 
     Bar = bar; 
    } 
} 

यह दुर्भाग्यपूर्ण है कि वहाँ अब यह सही करने का कोई रास्ता नहीं है कि है। आप (निर्माता श्रृंखलन का उपयोग दोहराव से बचने के कर सकते हैं।) निर्माता में मूल्य सेट करना होगा।

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

यह जब तक और सी # 5 सहित अप हुआ है नहीं है, लेकिन के लिए सी # 6 की योजना बनाई जा रही है एक निर्माता शरीर में।

+32

यह उन स्थानों में से एक है जहां वीबी.नेट टीम ने इसे सही पाया - वीबी में आप अपनी संपत्ति घोषित कर सकते हैं और इसे इस तरह की लाइन में सेट कर सकते हैं: 'सार्वजनिक संपत्ति माइप्रॉप स्ट्रिंग = "asdf" '। दुर्भाग्यवश, आप एक सार्वजनिक गेटर और एक निजी सेटर घोषित नहीं कर सकते जैसे आप सी # में कर सकते हैं। निश्चित नहीं है कि न तो टीम इस सुविधा को सही तरीके से कार्यान्वित करने का प्रबंधन क्यों कर सकती है। – mattmc3

+4

@ mattmc3: उन्हें लगभग सही मिला। किसी कारण से, वे प्रारंभिक रीडोनली ऑटो-प्रॉपर्टीज को अनुमति नहीं देते हैं, भले ही वे प्रारंभिक रीड-राइट गुणों की तुलना में अधिक समझदार हों। – supercat

+12

"जॉन स्कीट ने सी # 5.0 के बारे में पहले से ही एक पुस्तक लिखी है; वर्तमान में इसे बंद कर दिया गया है। तीन सालों में, एंडर्स हेजल्सबर्ग यह देखने के लिए पुस्तक खोलने जा रहा है कि भाषा डिजाइन टीम सही है या नहीं।" http://meta.stackexchange.com/a/9174 –

3

डिफ़ॉल्ट निर्माता में (और किसी भी गैर-डिफ़ॉल्ट वाले अगर आप किसी भी भी निश्चित रूप से है):

public foo() { 
    Bar = "bar"; 
} 

यह वह जगह है कोई कम प्रदर्शन नहीं है कि आपका मूल कोड मेरा मानना ​​है, क्योंकि वैसे भी दृश्यों के पीछे ऐसा होता है।

public class foo { 
    public foo(){ 
    Bar = "bar"; 
    } 
    public string Bar {get;set;} 
} 

आप एक और निर्माता मिल गया है, तो (यानी, एक है कि पैरामीटर लेता है) या निर्माताओं की एक गुच्छा आप कर सकते हैं हमेशा इस (बुलाया निर्माता है:

+0

यदि आपके पास अंतर्निहित क्षेत्र को प्रारंभ करने और स्वचालित संपत्ति का उपयोग न करने की तुलना में कई अलग-अलग कन्स्ट्रक्टर हैं, तो यह अधिक काम है - मुझे वास्तव में यह नहीं लगता कि उस परिदृश्य में ऑटो-प्रॉपर्टी से आपको क्या लाभ मिलता है ... – Bittercoder

+2

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

34

आप अपने वर्ग के निर्माता के माध्यम से यह कर सकते हैं चेनिंग):

public class foo { 
    private foo(){ 
    Bar = "bar"; 
    Baz = "baz"; 
    } 
    public foo(int something) : this(){ 
    //do specialized initialization here 
    Baz = string.Format("{0}Baz", something); 
    } 
    public string Bar {get; set;} 
    public string Baz {get; set;} 
} 

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

+1

हम्म मुझे लगता है कि मैंने वास्तव में 3 तरीके दिखाए हैं ...: पी –

+0

आखिरी उदाहरण अन्य कन्स्ट्रक्टर लॉजिक से पहले वैरिएबल शुरू होने वाले चर इनलाइन प्रारंभिक परिणामों में थोड़ा भ्रामक है। सामान्य पैटर्न कन्स्ट्रक्टर तर्क के बाद प्रारंभिकरण में आपका पैटर्न परिणाम होता है (कम से कम 3 में, int कुछ कन्स्ट्रक्टर के लिए)। –

+0

मैं इस धारणा से काम कर रहा था कि बार को केवल निर्माता द्वारा उपयोग नहीं किया जाना शुरू किया गया था, इसलिए प्रारंभिकरण की स्थिति समग्र निर्माण प्रक्रिया –

22

सी # 6 में यह संभव होगा।0:

public int Y { get; } = 2; 
संबंधित मुद्दे