2010-02-12 15 views
34

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

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

इस पर कोई विचार, क्या मुझे कुछ याद आ रहा है? अंतर है, जो उन लोगों के पाठ :)

//Immutable Tuple using public readonly fields 
public class Tuple<T1,T2> 
{ 
    public readonly T1 Item1; 
    public readonly T2 Item2; 
    public Tuple(T1 item1, T2 item2) 
    { 
     Item1 = item1; 
     Item2 = item2; 
    } 
} 

//Immutable Tuple using public properties and private readonly fields 
public class Tuple<T1,T2> 
{ 
    private readonly T1 _Item1; 
    private readonly T2 _Item2; 
    public Tuple(T1 item1, T2 item2) 
    { 
     _Item1 = item1; 
     _Item2 = item2; 
    } 
    public T1 Item1 { get { return _Item1; } } 
    public T2 Item2 { get { return _Item2; } } 
} 
बेशक

, तो आप स्वत: गुण इस्तेमाल कर सकते हैं (public T1 Item1 { get; private set; }) की तुलना में अधिक आसानी से कोड को पढ़ने के लिए है, लेकिन इस के लिए की

उदाहरण सिर्फ तुम 'सहमति अचल स्थिति' हो जाता है के रूप में 'गारंटी अचल स्थिति' के लिए विरोध ...

उत्तर

11

यह गुण से एक स्पष्ट चूक है कि आप की तरह कुछ नहीं लिख सकता है:

public T2 Item2 { get; readonly set; } 

मैं भी यकीन है कि readonly सबसे अच्छा शब्द मतलब करने के लिए "केवल निर्माता में सेट किया जा सकता" का उपयोग करने के लिए है नहीं कर रहा हूँ, लेकिन यही वह है जिसे हम अटक गए हैं।

यह वास्तव में एक विशेषता है जिसे कई लोगों ने अनुरोध किया है, इसलिए आइए आशा करते हैं कि इसे जल्द ही कुछ समय के सी # के एक काल्पनिक नए संस्करण में पेश किया जाएगा।

this related question देखें।

+2

हम्म, एक "सी # की काल्पनिक नए संस्करण" के बारे में अधिक पढ़ सकते हैं मुझे लगता है कि मुझे पता है कि आप किस ब्लॉग को पढ़ रहे हैं;) – Benjol

+1

हाँ, हम इस पर विचार कर रहे हैं। परिकल्पित। यह वास्तव में पहली नज़र में दिखाई देने की तुलना में एक और अधिक कठिन समस्या है। –

+2

@ एरिक लिपर्ट, अब आप हमें चिढ़ा रहे हैं। मैं जल्द ही कुछ कठिनाइयों के बारे में एक पोस्ट की उम्मीद करता हूं :) – Benjol

0

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

केवल दुर्लभ परिस्थितियों में मैं एक क्षेत्र - सार्वजनिक, आंतरिक, या अन्यथा खुलासा करता हूं। यह तब तक सही नहीं लगता जब तक कि एक संपत्ति लिखना {get;} मुझे देने के इच्छुक होने से अधिक समय लेता है।

0

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

अर्थशास्त्र पर भी विचार करें। यदि टी 1 संदर्भ प्रकार के बजाए एक मान प्रकार है, तो obj.Item1 प्राप्त करने से गेटटर में _Item1 की एक प्रति लौटाती है, जबकि गेटटर के बिना आइटम 1 तक पहुंचने से प्रतिलिपि प्राप्त नहीं होती है। इसका मतलब यह है कि जबकि आइटम 1 आंतरिक रूप से अपरिवर्तनीय हो सकता है, लौटा मूल्य प्रकार वस्तु नहीं है। मैं एक कारण के बारे में नहीं सोच सकता कि यह अच्छा चीज़ होगी, लेकिन यह एक अंतर है।

+0

जब आप किसी संपत्ति के माध्यम से वापस लौटते हैं तो प्रतिलिपि बनाने के बारे में क्या है? क्या आपके पास इसका संदर्भ है? – Benjol

+0

जब आप उन्हें पास करते हैं तो मूल्य प्रकारों की प्रतिलिपि बनाई जानी चाहिए। यह सी # काम करता है। –

+1

हाँ, लेकिन क्षेत्र को पास करने पर भी कॉपी क्यों नहीं किया जाएगा? मैं नहीं देख सकता कि यह एक समस्या होगी। – Benjol

3

आपको भविष्य में किसी सेटर में कोई तर्क जोड़ने की आवश्यकता नहीं हो सकती है, लेकिन आपको गेटर पर तर्क जोड़ने की आवश्यकता हो सकती है।

फ़ील्ड का खुलासा करने के बजाय गुणों का उपयोग करने के लिए यह पर्याप्त कारण है।

यदि मैं कठोर महसूस कर रहा हूं तो मैं पूर्ण अपरिवर्तनीयता (स्पष्ट readonly बैकिंग फ़ील्ड के साथ खुला गेटर्स और कोई सेटर्स नहीं) के लिए जाना चाहूंगा।अगर मैं आलसी महसूस कर रहा हूं तो शायद मैं "सहमत अपरिवर्तनीयता" (खुला गेटर्स और निजी सेटर्स के साथ ऑटो-प्रॉपर्टीज) के लिए जाऊंगा।

11

सी # 6.0 अब ऑटो-प्रॉपर्टी प्रारंभकर्ताओं का समर्थन करता है।

ऑटो-प्रॉपर्टी प्रारंभकर्ता अपनी घोषणा के भीतर सीधे गुणों को असाइन करने की अनुमति देता है। केवल पढ़ने योग्य गुणों के लिए, यह का ख्याल रखता है ताकि यह सुनिश्चित किया जा सके कि संपत्ति अपरिवर्तनीय है।

आप प्रारंभ कर सकते हैं केवल पढ़ने के लिए निर्माता में या का उपयोग कर स्वत: प्रारंभकर्ता गुण

public class Customer 
{ 
    public Customer3(string firstName, string lastName) 
    { 
     FirstName = firstName; 
     LastName = lastName; 
    } 
    public string FirstName { get; } 
    public string LastName { get; } 
    public string Company { get; } = "Microsoft"; 
} 

var customer = new Customer("Bill", "Gates"); 

आपने ऑटो-संपत्ति initializers here

संबंधित मुद्दे