2016-04-11 4 views
6

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

अभी मैं इस पशु कक्षा

public class Animals 
{ 
    //fields 
    private string name; 

    public Animals(string name) 
    { 
     this.name = name; 
    } 

    // default constructor 
    public Animals() 
    { } 

    //This is the problematic portion 
    public string Name { get; set; } 


    public void Bark() 
    { 
     Console.WriteLine("{0} said WoWOW", name); 
    } 

} 

यह मेरा मुख्य प्रोग्राम वर्ग है

class Program 
{ 
    static void Main(string[] args) 
    { 

     Console.WriteLine("Enter name: "); 
     string name = Console.ReadLine(); 
     Animals dog = new Animals(name); 
     dog.Bark(); 

     Animals cat = new Animals(); 
     Console.WriteLine("Enter second name: "); 
     cat.Name = Console.ReadLine(); 
     cat.Bark(); 


    } 
} 

उत्पादन इस प्रकार है। अंतिम पंक्ति मेरी समस्या

Enter name: 
    bob 
    bob said WoWOW 
    Enter second name: 
    sarah 
    said WoWOW //sarah is missing here 

है हालांकि जब मैं से गुणों में परिवर्तन {मिल; सेट} कक्षा में अपने पूर्ण संस्करण के लिए। यह सही आउटपुट आउटपुट करता है।

संपादित कोड

public class Animals 
{ 
    //fields 
    private string name; 

    public Animals(string name) 
    { 
     this.name = name; 
    } 

    public Animals() 
    { } 

    //apparently this is the correct way of making properties 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 


    public void Bark() 
    { 
     Console.WriteLine("{0} said WoWOW", name); 
    } 

} 

उत्पादन: // सारा अंतिम पंक्ति

Enter name: 
    bob 
    bob said WoWOW 
    Enter second name: 
    sarah 
    sarah said WoWOW 

मेरा प्रश्न है में मौजूद है: ऐसा क्यों है जब ऑटो गुण प्रयोग किया जाता है मैं नहीं मिलता है मेरी वांछित आउटपुट लेकिन जब मैं पूरी तरह से गुण लिखता हूं तो मुझे अपना वांछित परिणाम मिलता है। मेरे प्रश्न पर एक नज़र डालने के लिए धन्यवाद। उम्मीद है कि यह बहुत लंबा नहीं था! ;]

+2

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

उत्तर

6

यह काम करेगा:

public class Animals 
{ 
    //fields 
    private string name; // <-- You don't need it when you have auto properties 

    public Animals(string name) 
    { 
     Name = name;// <-- Using auto property 
    } 

    public string Name { get; set; } 

    public void Bark() 
    { 
     Console.WriteLine("{0} said WoWOW", Name);//<-- Using auto property 
    } 

} 

इसके अलावा, आप What are Automatic Properties in C# and what is their purpose? पर एक नज़र रखना चाहिए और Auto-Implemented Properties (C# Programming Guide)


साइड नोट 1: एक खाली, parameterless, सार्वजनिक निर्माता बेकार है अगर आपके पास अन्य कन्स्ट्रक्टर नहीं है। यह यहां सामान्य से अधिक है एक विलक्षण संज्ञा के साथ अपनी कक्षाओं नाम के लिए,: जो के रूप में बताया है, अगर, अपने उदाहरण में, आप इसे हटाने के लिए, आप नहीं var a = new Animals();

साइड नोट 2 कॉल करने के लिए सक्षम हो जाएगा Animal

+0

तो अगर मैं किसी संपत्ति का उपयोग करना चाहता हूं, तो मुझे कभी भी एक इंटियल फ़ील्ड घोषित करने की आवश्यकता नहीं है? चूंकि मैं अभी भी सीख रहा हूं: तब कोई फ़ील्ड कब घोषित करता है? – Nate

+0

@ नेट हाँ, यह है :) –

+2

अपने साइड नोट के संबंध में, खाली पैरामीटर रहित सार्वजनिक कन्स्ट्रक्टर केवल बेकार है यदि कोई अन्य रचनाकार नहीं है। इस उदाहरण में एक और कन्स्ट्रक्टर है, इसलिए खाली के बिना, आप 'नए पशु() ' –

4

ठीक है, कक्षा के ये दो सदस्य वास्तव में जुड़े नहीं हैं।

private string name; 

public string Name { get; set; } 

यहाँ क्या होता है कि आप क्षेत्र, और स्वत: संपत्ति जो स्वचालित रूप से अंतर्निहित क्षेत्र पैदा करता है और यह दूसरा क्षेत्र (नहीं एक आपके द्वारा बनाई गई) के साथ काम करता घोषित है।

आप स्वत: संपत्ति के गेटर और सेटर उपयोग कर सकते हैं, या इस के तरीकों को स्पष्ट रूप से (सामान्य संपत्ति का उपयोग कर) को परिभाषित:

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

ऑटो संपत्ति क्षेत्र पैदा करता है और स्वचालित रूप से आप इस प्रकार आपके समय की बचत के लिए ऊपर दिए गए कोड लागू करता है।यदि आप फ़ील्ड और प्रॉपर्टी बनाना चाहते हैं जो इस क्षेत्र के मूल्य को सेट (या प्राप्त) करके बस इसके साथ काम करता है तो ऑटो-प्रॉपर्टीज जाने का एक तरीका है। आप केवल ऑटो-प्रॉपर्टी को परिभाषित कर सकते हैं और get; और विधियों के साथ काम करता है।

public string Name 
{ 
    get { return name; } 

    // sets field value depending on condition 
    set { name = !string.IsNullOrEmpty(value) && value.Length < 20 ? value : name; } 
} 

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

// setter of this property is only accessible inside the class or sub-classes 
public string Name { get; protected set; } 
+0

जिसने पूरी तरह से मेरे प्रश्न का उत्तर दिया! मेरे संदेहों को स्पष्ट करने के लिए समय निकालने के लिए धन्यवाद! – Nate

+0

@Nate ने कुछ अतिरिक्त जानकारी के साथ अपना उत्तर अपडेट किया जो आपकी मदद कर सकता है – Fabjan

3

आप एक ऑटो संपत्ति का उपयोग करते हैं

public string Name { get; set; } 

कंपाइलर बैकिंग फ़ील्ड के रूप में "नाम" का उपयोग नहीं करता है।
इसके बजाय यह अनूठा नाम के साथ उसके अपने क्षेत्र उत्पन्न करता है:

[CompilerGenerated] 
private string <Name>k__BackingField; 

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

2

अपने कोड में आप ऑटो-प्रॉपर्टी Name घोषित करते हैं लेकिन आप इसका कभी भी उपयोग नहीं करते हैं। name क्षेत्र को संदर्भित करता है और Name संपत्ति को संदर्भित करता है

this is how your code is working

आवरण फर्क पड़ता है, यह क्या अपने कोड के साथ हो रहा है। वे इस संदर्भ में अलग-अलग चीजें हैं।

ऑटो-गुणों का उपयोग करते समय आपको फ़ील्ड घोषित करने की आवश्यकता नहीं है, संकलक उन्हें आपके लिए बनाएगा।

आपको फ़ील्ड घोषित करना चाहिए जब आप उन्हें अपनी कक्षा में निजी के रूप में उपयोग करेंगे, या जब आपको अधिक विस्तृत संपत्ति की आवश्यकता होगी।

तो क्षेत्र को हटाने और करने के लिए निर्माता को बदलने:

public Animals(string name) 
{ 
    // property Name receives constructor parameter name 
    Name = name; 
} 
संबंधित मुद्दे