2010-08-20 8 views
13
private List<Date> _dates; 

public List<Date> Dates 
{ 
    get { return _dates; } 
    set { _dates = value; } 
} 

यासी # गुण

public List<Date> Dates 
{ 
    get;   
    set;  
} 

मैं हमेशा पूर्व का इस्तेमाल किया है की सही उपयोग, यह गलत है या बुरा व्यवहार है? यह मेरे लिए कभी नहीं हुआ कि मैं सिर्फ दूसरे विकल्प का उपयोग कर सकता था। मुझे अंडरस्कोर से शुरू करने के लिए मेरे encapsulated चर होने की तरह है, इसलिए मैं उन्हें विधि पैरामीटर से अलग कर सकते हैं। और मैंने हमेशा ऐसा ही किया है।

क्या यह संभव है कि पहले विकल्प का उपयोग एक अतिरिक्त List<Date> वस्तु में परिणाम होगा instantiated जा रहा है और उसके बाद _dates के पूरे value से बदला जा रहा है, या यह है कि तुलना में अधिक बुद्धिमान है?

इसके अलावा, जो उद्योग में सबसे प्रमुख है या यह पूरी तरह से व्यक्तिपरक है?

+0

के संभावित डुप्लिकेट [सी # 3.0 ऑटो गुण - उपयोगी है या नहीं] (http://stackoverflow.com/questions/9304/c-sharp-3-0-auto- गुण-उपयोगी-या-नहीं) – nawfal

उत्तर

7

वे आंतरिक संकलित रूप में समकक्ष हैं, सिवाय इसके कि आप दूसरे रूप में संकलक उत्पन्न निजी चर का उपयोग नहीं कर सकते हैं।

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

कोडिंग परिप्रेक्ष्य से, मैं दूसरा संस्करण पसंद करता हूं जो अधिक कॉम्पैक्ट (लिखने के लिए कम, पढ़ने के लिए कम) है।

दूसरा वाक्यविन्यास सी # 3.0 में पेश किया गया था। तो पहला संस्करण पुराने कंपाइलरों के लिए अधिक अनुकूल होगा।

+0

पिछड़ा संगतता और संकलित कोड के बारे में अच्छी जानकारी, धन्यवाद। – Nobody

7

दोनों मूल रूप से समान हैं क्योंकि .NET स्वचालित गुणों को कैसे संकलित करता है। स्वचालित गुण .NET 3.5 के साथ उपलब्ध हो गए।

+1

3.0 वास्तव में http://msdn.microsoft.com/en-us/library/bb384054.aspx – CaffGeek

+2

@ चाड सी # 3.0, लेकिन .NET 3.5। –

+0

छूना! मैं हमेशा भूल जाता हूं कि संस्करण संख्या सिंक्रनाइज़ेशन से बाहर हैं – CaffGeek

19

यदि आप अपने गेटर/सेटर्स में किसी प्रकार का तर्क जोड़ना चाहते हैं तो पूर्व का उपयोग करें।

अन्यथा बाद वाले का उपयोग करें। यह चीजों को ज्यादा साफ करता है। तुम भी ऑटो गुणों का उपयोग करके केवल पढ़ने के लिए गुण प्राप्त कर सकते हैं:

public List<Date> Dates { get; private set; } 

या, यदि आप लोगों को संपत्ति के माध्यम से सूची आप पूर्व वाक्य रचना का सहारा कर सकते हैं के लिए किसी भी आइटम जोड़ने के लिए नहीं करना चाहती:

private List<Date> _dates = new List<Date>(); 
private ReadOnlyCollection<Date> _readOnlyDates = 
    new ReadOnlyCollection<Date>(_dates); 

public ReadOnlyCollection<Date> Dates 
{ 
    get { return _readOnlyDates; } 
} 
+0

मैं एक नया 'ReadOnlyCollection' वापस नहीं रखूंगा। आंतरिक रूप से यह सूची का संदर्भ रखता है ताकि कोई भी परिवर्तन दिखाई दे। – ChaosPandion

+1

मुद्दा यह है कि कॉलर इसे संशोधित करने में सक्षम नहीं होंगे। – recursive

+0

मैं एक निजी प्रॉपर्टी 'रीड-ओनली' के साथ एक ऑटो प्रॉपर्टी नहीं कहूंगा: इसे अभी भी उस कक्षा के भीतर से बदला जा सकता है जिसमें इसे परिभाषित किया गया है, यानी यह फ़ील्ड पर 'रीडोनली' कीवर्ड का पर्याय नहीं है। –

0

इससे कोई फर्क नहीं पड़ता। दूसरा सिर्फ चीनी है। मैं हमेशा दूसरे का उपयोग करता हूं क्योंकि यह क्लीनर है, लेकिन हर बार एक बार मुझे बैकिंग वैल्यू तक पहुंच की आवश्यकता होती है।

0

जब तक आपको यह सुनिश्चित करने की आवश्यकता नहीं है कि List<Date> गेटटर में प्रारंभ किया गया है तो आप दोनों संस्करणों के साथ ठीक हैं। मैं सिर्फ सुझाव है कि आप एक संस्करण का उपयोग कर रहे हैं और आप इसे अपने कोड में मिश्रण नहीं है ...

आप की जरूरत है यह प्रारंभ आप पहले संस्करण के लिए जाना है ...

private List<Date> _dates; 

public List<Date> Dates 
{ 
    get { if (_dates == null) _dates = new List<Date>(); return _dates; } 
    set { _dates = value; } 
} 
+1

यह मूर्खतापूर्ण है। बस "निजी सूची _डेट्स = नई सूची ()" या कन्स्ट्रक्टर में प्रारंभ करें। मुझे आलसी संदेह है- इस सरल सूची को शुरू करने से अधिक जटिल कोड के अलावा कुछ और खरीद जाएगा। – siride

+1

@ साइराइड - मैं सहमत हूं, अब अगर आप डेटाबेस से एक सूची शुरू कर रहे थे जो एक पूरी तरह से अलग कहानी है। – ChaosPandion

0

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

0

दोनों को लगभग उसी तरह संकलित किया गया है (मुझे नहीं पता कि बैकिंग फ़ील्ड का नाम विशेष रूप से वही होगा, लेकिन वे कार्यात्मक रूप से समतुल्य होंगे)।

आईआईआरसी, स्वचालित गुण (public List<Date> Dates {get; set;}) करने की क्षमता .NET 3.0 या 3.5 में जोड़ा गया था।

4

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

लगभग मेरी संपत्ति घोषणाओं के सभी देखने के लिए की तरह:

public bool IsBlah { get; private set; } 

इस बनाता है एक अच्छा पढ़ने-योग्य और संरक्षित गेटर।

लेकिन जब आप एक स्पष्ट समर्थन क्षेत्र चाहते बार देखते हैं:

private bool? _isBlah; 
public bool IsBlah 
{ 
    get 
    { 
     if (_isBlah == null) 
     { 
      // Do something expensive here and set _isBlah 
      _isBlah = true; 
     } 
     return _isBlah; 
    } 
} 
1

पूर्व मूल दृष्टिकोण है, बाद नए 'ऑटो गुण' सुविधा जिससे संकलक एक समर्थन क्षेत्र उत्पन्न करता है का एक उदाहरण है आपके लिए स्वचालित रूप से

कुछ लोगों को (अपने आप को शामिल) ऑटो गुणों से संकोच क्योंकि वाक्य रचना सार गुण समझने की भूल करने के लिए आसान है, वहाँ 'केवल पढ़ने के लिए' गुण के लिए कोई सुविधा नहीं है और निजी setters के साथ स्वत: संपत्तियों के लिए वाक्य रचना अनाड़ी है:

public List Dates 
{ 
    get; 
    private set; 
}

मुझे क्लास एपीआई के माध्यम से अपने वर्गों के आंतरिक कार्यान्वयन क्षेत्रों को एक्सेस करने में भी असहज लगता है।

+0

'मुझे क्लास एपीआई के माध्यम से अपने वर्गों के आंतरिक कार्यान्वयन को फ़ील्ड तक पहुंचने में असहज लगता है।' बिल्कुल! मैं जो भी उपयोग करता हूं उसके साथ रहूंगा। धन्यवाद – Nobody

1

दूसरी भिन्नता auto-implemented properties के रूप में जानी जाती है और इसे सी # 3.0 में पेश किया गया था (इसलिए आप इसे पहले क्यों सामना नहीं कर सकते थे)।

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

नोट करें कि आप अभी भी गुणों को प्रारंभ कर सकते हैं, आप इसे केवल कन्स्ट्रक्टर के माध्यम से करते हैं।

public class MyClass 
{ 

    public List<Date> Dates 
    { 
     get;   
     set;  
    } 

    public MyClass() 
    { 
     Dates = new List<Date>(); 
    } 

} 
0

जहां तक ​​मुझे याद है, मैंने हमेशा अपनी वस्तु के भीतर से मेरी सूची गुणों को प्रबंधित किया है, जिससे उन्हें पढ़ा जा सकता है।

private IList<DateTime> _dates; 

public MyClass() { 
    _dates = new List<DateTime>(); 
} 

public IList<DateTime> Dates { 
    get { 
     return _dates; 
    } 
} 

ऐसा करके, मैं आश्वासन देता हूं कि जब मैं इसे एक्सेस करता हूं तो मेरी सूची कभी भी शून्य नहीं होती है, क्योंकि ग्राहक इसे असाइन नहीं कर सकता है।

हालांकि, आपके उदाहरण के लिए, आपको केवल पूर्व दृष्टिकोण का उपयोग करने की आवश्यकता है यदि आपको संपत्ति प्राप्त करने या सेट करने पर किसी प्रकार की तर्क की आवश्यकता है। अन्यथा, स्वचालित गुण वही वही करते हैं जो आप चाहते हैं, केवल एक निजी क्षेत्र में मूल्य प्राप्त करना और सेट करना। इसके अलावा, { get; set; } पठनीयता में सुधार करता है और मेरे विनम्र दृष्टिकोण में, अन्य प्रोग्रामर आपकी मंशा को समझने में सहायता करता है।

उदाहरण के लिए:

public class MyClass { 
    private IList<DateTime> _dates; 

    public IList<DateTime> Dates { 
     get { 
      return _dates; 
     } set { 
      _dates = value; 
     } 
    } 
} 

बनाम

public class MyClasse { 
    public IList<DateTime> Dates { get; set; } 
} 

दूसरा तरीका यह leaner और तेज, क्या इरादा है बनाता है कम से कम मेरे लिए,। और यह कक्षा को कोड करने के लिए तेज़ी से हो जाता है, जब गेटर और सेटर के अंदर कोई तर्क आवश्यक नहीं होता है।

अन्यथा, कोई दूसरे की तुलना में बेहतर नहीं है और यह वही करता है, जो किसी तर्क के साथ संपत्ति के मूल्य को प्राप्त करने और सेट करने की बात करता है।

सबसे महत्वपूर्ण बात यह है कि आपको अपने कोड से सहज रहने की आवश्यकता है। यदि यह आपके लिए समाप्त होता है तो कोई सुधार नहीं होता है, और आपको यह पसंद है कि आप ऐसा कर रहे हैं। =)

+0

क्लीनर कोड के साथ एक ही परिणाम प्राप्त करने के लिए आप अपने अंतिम उदाहरण में 'निजी सेट' जोड़ सकते हैं। लेकिन 'IList' के संदर्भ को ध्यान में रखते हुए भी ध्यान रखें कि इसका अर्थ केवल पढ़ने के लिए नहीं है, क्योंकि' IList' 'Add', 'निकालें', 'साफ़ करें' इत्यादि का समर्थन करता है। अनुमोदित, यदि आपका कॉलर वास्तव में सूची को बदलना चाहता है, वे इससे कोई फर्क नहीं पड़ता कि आप उन्हें क्या सौंपते हैं। –

+0

@ मैट ग्रीर: हाँ, वास्तव में! आम तौर पर मुझे जो चाहिए वह है, जिसका अर्थ है कि सूची में से किसी को() या निकालें() को अनुमति दें, अन्यथा मैं उच्च पदानुक्रम स्तर वस्तु के लिए जाऊंगा। इसके अलावा, सी # की क्षमता ने गेटर के लिए एक एक्सेसर स्कोप परिभाषित किया है, और दूसरा सेटटर के लिए, यह काम करने के लिए बहुत लचीला बनाता है। यह कई अन्य लोगों में से एक बात है जो मुझे सी # के साथ काम करने से चूकती हैं, क्योंकि मैं वर्तमान में वीबी.नेट 2.0 में काम कर रहा हूं। –

1

मैं व्यक्तिगत रूप से पहली विधि पसंद करता हूं क्योंकि यह आपको रिटर्न से पहले कुछ संचालन करने की अनुमति देता है।

ईजी। (ए वास्तव में गरीब उदाहरण)

private int _limit; 
    private int _onHand; 
    private bool returnToVendor; 

    public Item(int limit, int onHand) 
    { 
     _limit = limit; 
     _onHand = onHand; 
    } 

    public int ReturnStock 
    { 
     get 
     { 
     if(_onHand > _limit) 
     { 
      returnToVendor = true; 
      return _onHand; 
     } 
     } 

     set 
     { 
      _onHand = value; 

      if(_onHand < _limit) 
      { 
       returnToVendor = false; 
      } 
     } 
    } 
संबंधित मुद्दे