विभिन्न गटर शैलियों के बीच सी # में अंतर


154

मैं कभी-कभी गेट्टर के गुणों में संक्षिप्तता देखता हूं। जैसे वे दो प्रकार:

public int Number { get; } = 0

public int Number => 0;

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

जवाबों:


266

हां, दोनों ही पढ़े-लिखे हैं, लेकिन एक अंतर है। पहले एक में, एक बैकिंग फ़ील्ड है जो कि कंस्ट्रक्टर के निष्पादित होने से पहले 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, तो इसका मूल्यांकन किया जाएगा, इसलिए आपको संभावित रूप से अलग परिणाम मिलेगा।


23
ध्यान दें कि दूसरा संस्करण हमेशा समान मान नहीं लौटाता है। एक अच्छा उदाहरण है यदि आप लौटते हैं random.NextInt()। पहला संस्करण मूल्यांकन करेगा कि एक बार और हमेशा एक ही मूल्य है। दूसरा हर बार एक नया मान लौटाएगा।

248

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

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

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

    public DateTime Now => DateTime.Now;
}

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

स्पष्टीकरण :

पहला संस्करण ("प्रारंभ") एक प्रारंभिक मूल्य की आपूर्ति करता है जो निर्माणकर्ता द्वारा अधिलेखित भी हो सकता है। तो इसका मूल्यांकन सिर्फ एक बार किया जाता है।
दूसरा संस्करण ("नाउ") अभिव्यक्ति प्रदान करता है जो इस संपत्ति का "गेट्टर" होगा। इसलिए हर बार संपत्ति पढ़ने के बाद इसका मूल्यांकन किया जाता है। वहाँ भी एक समर्थन क्षेत्र है कि कंस्ट्रक्टर अधिलेखित कर सकते हैं नहीं है।


26
मुझे लगता है कि यह सबसे महत्वपूर्ण अंतर है।
मैथ्यू

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

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

21

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

पहला उदाहरण

public int Number { get; } = 0

पहला उदाहरण एक गेट्टर-ओनली ऑटो प्रॉपर्टी है । गेट-ओनली ऑटो-प्रॉपर्टी के बैकिंग क्षेत्र को स्पष्ट रूप से आसानी से घोषित किया जाता है।

दूसरा उदाहरण

public int Number => 0;

और दूसरा उदाहरण संपत्ति जैसे फ़ंक्शन सदस्यों पर अभिव्यक्ति निकाय है । ध्यान दें कि कोई भी getकीवर्ड नहीं है : यह अभिव्यक्ति बॉडी सिंटैक्स के उपयोग से निहित है।

दोनों पठनीय हैं।


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

2
@ मर्टिनबोनर ... लेकिन केवल कंस्ट्रक्टर में।
डेनिस कुइपर्स

5
या, हमेशा की तरह, प्रतिबिंब के माध्यम से (मामूली नाइटपैकिंग)
मार्को एमपीपी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.