2017-09-05 7 views
151

मुझे कभी-कभी गेटटर के गुणों में संक्षेप में दिखाई देता है। जैसे उन दो प्रकार:विभिन्न गेटर शैलियों के बीच सी # में अंतर

public int Number { get; } = 0 

public int Number => 0; 

क्या कोई मुझे बता सकता है कि उन दोनों के बीच कोई अंतर है या नहीं। वे कैसे व्यवहार करते हैं? क्या वे दोनों केवल पढ़ने के लिए हैं?

उत्तर

262

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

दूसरे में, गेटर केवल हर क्षेत्र में 0 लौटाता है, जिसमें कोई फ़ील्ड शामिल नहीं होता है।

तो सब पर किसी भी स्वचालित रूप से लागू किया गुण या अभिव्यक्ति शरीर के सदस्यों का उपयोग कर से बचने के लिए, हमने:

पहले संस्करण

private readonly int _number = 0; 
public int Number { get { return _number; } } 

दूसरा संस्करण

public int Number { get { return 0; } } 

एक अंतर का स्पष्ट उदाहरण इस तरह देखा जा सकता है:

public DateTime CreationTime { get; } = DateTime.UtcNow; 
public DateTime CurrentTime => DateTime.UtcNow; 

आप एक ही वस्तु बनाते हैं, तो इसके CreationTime संपत्ति हमेशा ही परिणाम प्राप्त होगा - क्योंकि यह एक केवल पढ़ने के लिए क्षेत्र में संग्रह किया गया है, वस्तु निर्माण पर प्रारंभ। हालांकि, हर बार जब आप CurrentTime संपत्ति तक पहुंचते हैं, तो इसका मूल्यांकन करने के लिए DateTime.UtcNow का कारण बन जाएगा, इसलिए आपको संभावित रूप से अलग-अलग परिणाम मिलेंगे।

+22

ध्यान दें कि दूसरा संस्करण हमेशा एक ही मान नहीं देता है। एक अच्छा उदाहरण यह है कि यदि आप 'random.extInt()' वापस करते हैं। पहला संस्करण मूल्यांकन करेगा कि एक बार और हमेशा एक ही मूल्य होगा। दूसरा हर बार एक नया मूल्य वापस करेगा। – Hosch250

20

ये सी # 6 भाषा विशेषताएं हैं।

पहले उदाहरण

public int Number { get; } = 0 

पहला उदाहरण एक getter-only auto property है। केवल गेटटर-केवल ऑटो-प्रॉपर्टी का बैकिंग फील्ड पूरी तरह से पढ़ा गया है।

दूसरा उदाहरण

public int Number => 0; 

और दूसरा उदाहरण expression bodies on property-like function members है। ध्यान दें कि get कीवर्ड नहीं है: यह अभिव्यक्ति बॉडी सिंटैक्स के उपयोग से निहित है।

दोनों पढ़ रहे हैं।

+4

... लेकिन जैसा कि जॉन स्कीट बताता है, आप उस मूल्य को बदल सकते हैं जो पहले व्यक्ति लौटाता है। –

+1

@ मार्टिनबोनर ... लेकिन केवल निर्माता में। –

+4

या हमेशा के रूप में, प्रतिबिंब (मामूली नाइटपिकिंग) के माध्यम से –

246

एक अंतर यह है कि 0 का मूल्यांकन किया जाता है: ऑब्जेक्ट निर्माण या जब संपत्ति का उपयोग किया जाता है।

आप दिनांक समय गुणों के साथ इस बेहतर देख सकते हैं:

class SomeTestClass 
{ 
    public DateTime Start { get; } = DateTime.Now; 

    public DateTime Now => DateTime.Now; 
} 

Start संपत्ति (की जब उदाहरण के लिए बनाया गया था) एक ही समय लौट रहा रखता है, जबकि Now परिवर्तन वर्तमान समय को प्रतिबिंबित करने के।

स्पष्टीकरण:

पहले संस्करण ("प्रारंभ") एक प्रारंभिक मूल्य है कि निर्माता द्वारा ओवरराइट किया जा सकता है प्रदान करता है। तो यह सिर्फ एक बार मूल्यांकन किया जाता है।
दूसरा संस्करण ("अब") अभिव्यक्ति प्रदान करता है जो इस संपत्ति का "गेटटर" होगा। इसलिए जब भी संपत्ति पढ़ी जाती है तो इसका मूल्यांकन किया जाता है। यहां तक ​​कि एक बैकिंग फ़ील्ड भी नहीं है जिसे कन्स्ट्रक्टर ओवरराइट कर सकता है।

+24

यह मुझे लगता है कि यह सबसे महत्वपूर्ण भेद है। – Matthew

+13

स्वीकृत उत्तर सबसे सटीक उदाहरण कोड में अंतर को परिभाषित करता है, लेकिन यह दो संरचनाओं में एक और अधिक उपयोगी अंतर बताता है। –

+2

वाह, आपको प्रसिद्ध जॉन स्कीट की तुलना में अधिक वोट मिले। –

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