2009-10-16 14 views
7

मैंने इस विषय के बारे में कुछ चर्चाएं पढ़ी हैं, और कुछ ऐसा है जो मुझे समझ में नहीं आता है।संपत्ति बनाम फंक्शन (विशेष रूप से .NET)

सबसे आम उत्तर यह प्रतीत होता है: कैश किए गए डेटा को वापस करने के लिए केवल पढ़ने के लिए प्रॉपर्टी का उपयोग करें, गैर-कैश किए गए डेटा को वापस करने के लिए फ़ंक्शन का उपयोग करें। केवल एक लिखित संपत्ति का उपयोग न करें, क्योंकि "यह समझ में नहीं आता है"।

इसके लिए कोई प्रदर्शन कारण नहीं है। आईएल में, माइप्रोपर्टी get_MyProperty और set_MyProperty विधियों के रूप में मौजूद है। एकमात्र कारण स्पष्ट रूप से है कि उपर्युक्त उत्तर माना जाना चाहिए।

ठीक है, तो रीडऑनली प्रॉपर्टी के साथ क्यों परेशान है? क्यों न सिर्फ निजी के बजाय परिवर्तनीय सार्वजनिक बनाते हैं? फिर गुण से परेशान क्यों हैं? कैश डेटा -> सार्वजनिक चर, गैर-कैश डेटा -> फ़ंक्शन, डेटा लिखना -> उप

चलिए सभी उपरोक्त भूल जाते हैं, और गुणों को एक आसान सुविधा के रूप में उपयोग करते हैं? डेटा प्राप्त करने और सेट करने के लिए एक 'आइटम'। यह जानने के लिए सामान्य ज्ञान का उपयोग करें कि कोई गेट कैश डेटा वापस नहीं करेगा (संभवतः देरी के परिणामस्वरूप)।

-Edit- मुझे लगता है कि लोग कम या ज्यादा सहमत हैं कि गुण सर्वोत्तम विकल्प हैं। मुझे समझ में नहीं आया कि मुझे इतनी सारी चर्चा क्यों मिलीं जहां लोग गुणों के खिलाफ वकालत कर रहे थे।

+1

आपका प्रश्न वास्तव में क्या है? आपका अंतिम अनुच्छेद या तो आपके प्रश्न का विरोध करता है या अपना उत्तर प्रदान करता है। –

+0

मेरा अंतिम अनुच्छेद मेरी राय प्रदान कर रहा है। मैं समझौते या असहमति की तलाश में हूं (प्रदान किए गए कारणों से)। – Stijn

+4

http://stackoverflow.com/questions/1019571/why-do-we-use-net-properties-instead-of-plain-old-get-set-functions – Jimmy

उत्तर

13

केवल गुणों को पढ़ने के लिए एक अच्छा कारण मूल्यों की गणना की जाती है। इस मामले में निर्यात करने के लिए कोई चर नहीं है।

उदाहरण

public class Person { 
    private readonly DateTime _birthday; 
    public int Age { get { return (DateTime.Now - _birthday).TotalYears; } } 
    ... 
} 

इस मामले _birthday एक संपत्ति के रूप में बेनकाब करने के लिए किया जाए या एक क्षेत्र निश्चित रूप से बहस का मुद्दा है में लिए

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

3

ऑटो गुणों की तुलना में गुणों के लिए अधिक है। यदि आप कार्य करें:

public int MyProp { 
    get { 
     // Do some processing 
     return someValue; 
    } 

    set { 
     // Do some processing 
     DoMyProcess(value); 
    } 
} 

और अन्य कोड:

public int MyProp { public get; public set; } 

तो यह वास्तव में से

public int MyProp; 

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

+0

गुणों का यह "लाभ" बहुत अधिक जोर दिया जाता है , मेरी राय में। निश्चित रूप से, उन लोगों के लिए बहुत महत्वपूर्ण है जो बड़ी संख्या में "बाइनरी उपभोक्ताओं" के साथ पुस्तकालयों, ढांचे, आदि लिख रहे हैं। लेकिन अधिकांश .NET परियोजनाओं के लिए मैंने काम किया है, "दुनिया को पुनर्निर्माण करना" आसान था। –

+0

@ डैन: आप सही हैं, 9 0% परियोजनाओं के लिए मैं काम करता हूं, यह कोई बड़ा सौदा नहीं है। किसी और चीज की तरह, गुण एक उपकरण हैं - यदि वे आपकी मदद करते हैं तो उनका उपयोग करें, अगर वे नहीं करते हैं तो उन्हें अनदेखा करें। हालांकि, कारणों पर जोर दिया जाता है, यही कारण है कि लोग जावा में गेटर्स और सेटर्स लिखते हैं, या फिर भी अगर लोग 'if (foo == 0)' के बजाय 'if (0 == foo) 'लिखते हैं- यह है एक रक्षात्मक कोडिंग तंत्र जो आदत बन जाता है। कई लोग तर्क देंगे कि आदत प्रयास के लायक है। दोबारा, अगर यह आपकी मदद करता है, तो इसका इस्तेमाल करें। –

+0

सी # 3 के ऑटो-कार्यान्वित गुणों के साथ, मैं यहां अपस्ट्रीम तैरने की कोशिश नहीं करता हूं। फिर भी, मेरे अधिकांश उपयोगों के लिए, एक फ़ील्ड ठीक काम करेगा - और यदि मुझे कभी भी एक स्पष्ट गेट/सेट की आवश्यकता होती है, तो किसी संपत्ति में बदलना कोई बड़ा सौदा नहीं होगा क्योंकि मैं बस सब कुछ पुनर्निर्माण करता हूं। हां, कुछ कोने के मामले ऐसे 'रेफरी' पैरामीटर हैं जो फ़ील्ड से किसी संपत्ति में स्विच करते समय टूट जाएंगे ... –

3

गुण विधि-आधारित संचालन के लिए सुविधाजनक विकल्प हैं। एक संपत्ति-गेटर-सेटर और एक विधि जो एक ही क्रिया करता है के बीच कोई कार्यात्मक अंतर नहीं है; वास्तव में, यदि आप आईएल देखते हैं तो आपको संपत्ति प्राप्तकर्ताओं को "प्राप्त करें" और/या "सेट" विधियों द्वारा प्रतिस्थापित किया जाएगा।

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

1

"कैश डेटा -> सार्वजनिक चर" - बुरा विचार। यह किसी अन्य वर्ग को कैश किए गए डेटा को संशोधित करने की अनुमति देगा। साथ ही, कैशिंग के लिए डेटा की गणना करना महंगा हो सकता है: केवल पढ़ने-योग्य संपत्ति का उपयोग करके आप संपत्ति तक पहुंचने तक गणना को स्थगित कर सकते हैं।

0

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

5

कारण # 1 = गुण डेटा-बाध्यकारी में उपयोग किया जा सकता है। तरीके नहीं कर सकते हैं।

कारण # 2 = घड़ी विंडो को डिबग करने पर गुण स्वचालित रूप से गुणों का खुलासा करेंगे या ऑब्जेक्ट का विस्तार करेंगे। तरीकों को स्वचालित रूप से इस तरह से नहीं देखा जाता है।

मुझे कुछ जगह पढ़ना याद है कि पढ़ने की संपत्ति ऑब्जेक्ट स्थिति को नहीं बदलनी चाहिए। मुझे लगता है कि विशेष रूप से कारण # 2 पर विचार करने के लिए एक अच्छा अभ्यास है। जैसे ही आप किसी ऑब्जेक्ट को देखते हैं और इसे घड़ी में विस्तारित करते हैं, ऑब्जेक्ट्स स्टेटस को बदला जा सकता है जिससे डीबगिंग को और अधिक कठिन बना दिया जा सकता है।

यदि एक महंगी संपत्ति दुर्घटना से बंधी है तो यह गंभीर प्रदर्शन समस्याओं को पेश कर सकती है। (गुण डेटा बाइंडिंग से गुणों को "छुपाएं" कर सकते हैं लेकिन केवल उन्हें विधियों का मतलब है कि आपको इसके बारे में चिंता करने की ज़रूरत नहीं है।)

गुण विंडो विकास के लिए सुविधाएं हैं। वे अलग तरह से "पुराना" कर रहे हैं डिजाइनरों आदि में

(मैं कभी कभी बस कुछ चर का पर्दाफाश लेकिन मैं उन्हें नाम के रूप में मैं करूंगा एक संपत्ति तो बजाय

पूर्णांक mCounter = 0;।।

मैं बस ऐसा

पूर्णांक काउंटर = 0 ;.

अगर मैं भविष्य मैं एक ही नाम के साथ संपत्ति बनाने में कुछ बिंदु पर "अतिरिक्त सामग्री" करते हैं और mCounter चर नाम बदलें। वैसे यह आलस्य पर है करने के लिए है मेरा हिस्सा और मैं वास्तव में फिर से नहीं कर रहा हूँ इसे सराहना करो। बस इसे एक संपत्ति में लपेटें।)

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