C # 3.0 ऑटो-गुण - उपयोगी या नहीं? [बन्द है]


155

नोट: यह तब पोस्ट किया गया जब मैं C # शुरू कर रहा था। 2014 के ज्ञान के साथ, मैं वास्तव में कह सकता हूं कि ऑटो-प्रॉपर्टी सबसे अच्छी चीजों में से एक है जो कभी भी सी # भाषा के साथ हुई।

मैं निजी और सार्वजनिक क्षेत्र का उपयोग करके C # में अपनी संपत्ति बनाने के लिए उपयोग किया जाता हूं:

private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

अब .NET 3.0 के साथ , हमें ऑटो-प्रॉपर्टी मिली:

public string Title { get; set; }

मुझे पता है कि यह एक दार्शनिक / व्यक्तिपरक प्रश्न है, लेकिन क्या प्रत्येक क्षेत्र के लिए पांच पंक्तियों को सहेजने के अलावा इन ऑटो-गुणों का उपयोग करने का कोई कारण है? मेरी निजी पकड़ यह है कि वे गुण मुझसे सामान छिपा रहे हैं, और मैं काले जादू का बहुत बड़ा प्रशंसक नहीं हूं।

वास्तव में, छिपा हुआ निजी क्षेत्र डिबगर में भी दिखाई नहीं देता है, जो ठीक है कि तथ्य यह है कि गेट / सेट फ़ंक्शंस कुछ भी नहीं करते हैं। लेकिन जब मैं वास्तव में कुछ गटर / सेटर लॉजिक को लागू करना चाहता हूं, तो मुझे वैसे भी निजी / सार्वजनिक जोड़ी का उपयोग करना होगा।

मुझे यह लाभ दिखाई देता है कि मैं बाद में गेट्टर / सेटर लॉजिक को बदलने की क्षमता खोए बिना बहुत सारे कोड (एक बनाम छह लाइनें) बचा लेता हूं, लेकिन फिर मैं पहले से ही ऐसा कर सकता हूं कि बिना किसी सार्वजनिक क्षेत्र को "पब्लिक स्ट्रिंग टाइटल" घोषित किए बिना। {पाने की आवश्यकता; सेट; } ब्लॉक, इस प्रकार और भी अधिक कोड की बचत।

तो, मैं यहाँ क्या याद कर रहा हूँ? कोई भी वास्तव में ऑटो-संपत्तियों का उपयोग क्यों करना चाहेगा?


86
"मेरी निजी पकड़ यह है कि वे गुण मुझसे सामान छिपा रहे हैं, और मैं काले जादू का बहुत बड़ा प्रशंसक नहीं हूं।" है ना? आप जानते हैं कि संकलक हर समय आपसे एक टन छुपाता है, है ना? जब तक आप असेंबली (या अधिक सटीक, वास्तविक 1 और अपने कोड के लिए 0) लिख रहे हैं, तब तक आप जो भी लिख रहे हैं, वह आपसे सामान छिपा रहा है।
बजे चार्ल्स बॉउंग

जवाबों:


118

हम स्टैक ओवरफ्लो में हर समय उनका उपयोग करते हैं।

आप गुण बनाम सार्वजनिक चर की चर्चा में भी रुचि रख सकते हैं । IMHO है कि वास्तव में यह एक प्रतिक्रिया है, और उस उद्देश्य के लिए, यह बहुत अच्छा है।


62

हां, यह सिर्फ कोड सेव करता है । जब आप उनमें से लोड करते हैं तो यह पढ़ना आसान होता है। वे लिखने के लिए तेज हैं और बनाए रखना आसान है। सेविंग कोड हमेशा एक अच्छा लक्ष्य होता है।

आप अलग-अलग स्कोप सेट कर सकते हैं:

public string PropertyName { get; private set; }

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

C # 6 के अनुसार आप सही readonlyगुण भी बना सकते हैं - अर्थात अपरिवर्तनीय गुण जिन्हें कंस्ट्रक्टर के बाहर नहीं बदला जा सकता है:

public string PropertyName { get; }

public MyClass() { this.PropertyName = "whatever"; }

संकलन समय पर जो बन जाएगा:

readonly string pName;
public string PropertyName { get { return this.pName; } }

public MyClass() { this.pName = "whatever"; }

बहुत सारे सदस्यों के साथ अपरिवर्तनीय कक्षाओं में यह बहुत अधिक कोड बचाता है।


"तो आप किसी भी कार्यक्षमता खोना नहीं है।" आप उन्हें कैसे डीबग करते हैं?
वाल

2
@वल - डिबग करने के लिए क्या है? उस दृष्टिकोण से आप मूल रूप से सदस्य चर के साथ काम कर रहे हैं।
कीथ

6
@वाल - आप उन पर ब्रेकपॉइंट लगा सकते हैं, जैसे आप किसी सदस्य चर का उपयोग कर सकते हैं, वैसे ही आप उनमें कदम नहीं रख सकते। लेकिन तुम क्यों करना चाहते हो? ऑटो-प्रॉपर्टी वास्तव में क्या है, दोनों तुच्छ और ऑटो-जनरेट किए गए हैं, अगर आपको बग मिल गए हैं तो एक जगह है जहां वे होने की संभावना नहीं है।
कीथ

3
हमें इसे कीथ के बाहर ले जाने की आवश्यकता हो सकती है। :)
वाल

1
लेकिन ठीक है, मान लें कि आपके पास myObj.Title के लिए कई सेटर कॉल हैं ... आप यह देखना चाहते हैं कि "टेक्स्ट" से मान शून्य में बदल जाता है, यानी एक सशर्त ब्रेकप्वाइंट। आप कैसे करते हैं? तुम भी सेटर पर एक ब्रेकपाइंट सेट नहीं कर सकते
वाल

45

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

  1. जब आप किसी प्रॉपर्टी के लिए कर सकते हैं, तो आप किसी फ़ील्ड पर डेटाबाइंड नहीं कर सकते
  2. यदि आप एक फ़ील्ड का उपयोग करना शुरू करते हैं, तो आप बाद में (आसानी से) उन्हें एक संपत्ति में नहीं बदल सकते
  3. कुछ विशेषताएं हैं जो आप एक संपत्ति में जोड़ सकते हैं जिसे आप एक फ़ील्ड में नहीं जोड़ सकते

7
"यदि आप एक क्षेत्र का उपयोग करना शुरू करते हैं, तो आप बाद में (आसानी से) उन्हें एक संपत्ति में नहीं बदल सकते हैं", क्षमा करें लेकिन क्यों?
होमम

6
@Homam मुख्य रूप से, कोई भी उपभोक्ता कोड जो आपके खेतों पर प्रतिबिंब का उपयोग करता है, टूट जाएगा, क्योंकि उन्हें FieldInfo का उपयोग करके PropertyInfo से स्विच करना होगा।
WCWedin

8
@Homam इसके अलावा, प्रॉपर्टी में फ़ील्ड बदलने से बाइनरी कॉम्पिटिबिलिटी टूट जाती है, जिससे फ़ील्ड के सभी उपभोक्ताओं को फिर से संगठित होने की आवश्यकता होती है।
ओड्रेड

1
पुनर्संयोजन और प्रतिबिंब मुद्दों को एक तरफ, विजुअल स्टूडियो का उपयोग करके फ़ील्ड्स को एनक्रिप्ट करना बहुत आसान है: Ctrl-R + E आपको उचित गेटर्स / सेटर्स के साथ एक फ़ील्ड को संपत्ति में बदलने की अनुमति देगा। (या फ़ील्ड को राइट-क्लिक करें, री-फैक्टर, एनकैप्सुलेट फ़ील्ड)।
जोब्रॉकहॉस

@ होम्मम फ़ील्ड्स लैवल्यूज़ (वे चर हैं), और गुण नहीं हैं। जब यह एक संपत्ति थी तब स्टफ संकलित नहीं हो सकता था जब यह एक संपत्ति थी।
मार्क

29

मुझे व्यक्तिगत रूप से ऑटो-गुण पसंद हैं। कोड की लाइनों को बचाने में क्या गलत है? यदि आप गेटर्स या सेटर में सामान करना चाहते हैं, तो बाद में उन्हें सामान्य प्रॉपर्टी में बदलने की कोई समस्या नहीं है।

जैसा कि आपने कहा था कि आप खेतों का उपयोग कर सकते हैं, और यदि आप उनसे तर्क जोड़ना चाहते हैं तो बाद में आप उन्हें गुणों में बदल देंगे। लेकिन यह प्रतिबिंब के किसी भी उपयोग (और संभवतः कहीं और?) के साथ समस्याएं पेश कर सकता है।

इसके अलावा गुण आपको गेटर और सेटर के लिए अलग-अलग एक्सेस स्तर सेट करने की अनुमति देते हैं जो आप एक क्षेत्र के साथ नहीं कर सकते हैं।

मुझे लगता है कि यह वैर कीवर्ड जैसा ही है। व्यक्तिगत पसंद का मामला।


29

ब्रजेन स्ट्रॉस्ट्रुप से, सी ++ के निर्माता:

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

और क्या आपको पता है? वह सही है। कितनी बार आप निजी क्षेत्र को एक सेट और सेट में लपेट रहे हैं, वास्तव में गेट / सेट के भीतर कुछ भी किए बिना, क्योंकि यह "ऑब्जेक्ट ओरिएंटेड" चीज़ है। यह समस्या का Microsoft समाधान है; वे मूल रूप से सार्वजनिक क्षेत्र हैं जिन्हें आप बांध सकते हैं।


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

18

एक बात किसी को नहीं लगती है कि ऑटो-प्रॉपर्टीज दुर्भाग्य से अपरिवर्तनीय वस्तुओं (आमतौर पर अपरिवर्तनीय संरचनाओं) के लिए उपयोगी नहीं हैं। क्योंकि इसके लिए आपको वास्तव में करना चाहिए:

private readonly string title;
public string Title
{
    get { return this.title; }
}

(जहां फ़ील्ड को उत्तीर्ण पैरामीटर के माध्यम से कंस्ट्रक्टर में आरंभीकृत किया जाता है, और उसके बाद ही पढ़ा जाता है।)

तो यह एक सरल get/ private setautoproperty पर लाभ है ।


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

@ कीथ: आपका पहला वाक्य तथ्यात्मक रूप से गलत लगता है।
Domenic

3
public string Title { get; private set; }वास्तव में एक ही बात में परिणाम की तरह नहीं होगा ? आप इसे कक्षा के अंदर से निश्चित रूप से बदल सकते हैं, लेकिन अगर आपको लगता है कि आपको अन्य समस्याएं हैं ...: p
Svish 31'09

2
@ सविश - उस तर्क से C # में आसानी से पढ़े जाने वाले कीवर्ड का उपयोग कभी नहीं किया जाना चाहिए क्योंकि इसके उपयोग का मतलब यह होगा कि हम इन "विभिन्न समस्याओं" को छिपा रहे थे
Zaid Masud

2
मेरा बस इतना मतलब है कि बाहरी एपीआई तरह के दृष्टिकोण से, इससे बहुत फर्क नहीं पड़ेगा। और इसलिए, यदि चाहें तो ऑटो-प्रॉपर्टी का इस्तेमाल किया जा सकता है। सबसे अच्छी बात यह होगी कि अगर आप कुछ ऐसा कर सकते हैंpublic string Title { get; private readonly set; }
Svish 13'11

12

मैं हमेशा सार्वजनिक फ़ील्ड के बजाय गुण बनाता हूँ क्योंकि आप इंटरफ़ेस परिभाषा में गुणों का उपयोग कर सकते हैं, आप सार्वजनिक फ़ील्ड का उपयोग इंटरफ़ेस परिभाषा में नहीं कर सकते।


8

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


5

मैं हर समय ऑटो-प्रॉपर्टी का इस्तेमाल करता हूं। C # 3 से पहले मुझे सभी टाइपिंग से परेशान नहीं किया जा सकता था और इसके बजाय सिर्फ सार्वजनिक चर का उपयोग किया जाता था।

केवल एक चीज जो मुझे याद आती है वह यह करने में सक्षम है:

public string Name = "DefaultName";

आपको अपने कंस्ट्रक्टरों की संपत्तियों में चूक को शिफ्ट करना होगा। दिलचस्प :-(


4
C # 6 से ऑटो-प्रॉपर्टी इनिशियलाइज़र के साथ आप जल्द ही ऐसा करने में सक्षम होंगे: public string Name { get; set; } = "DefaultName"; blogs.msdn.com/b/csharpfaq/archive/2014/11/20/…
कार्लोस

5

मुझे लगता है कि कोई भी निर्माण जो सहज है और कोड की लाइनों को कम करता है एक बड़ा प्लस है।

उन प्रकार की विशेषताएं हैं जो रूबी जैसी भाषाओं को इतना शक्तिशाली बनाती हैं (और गतिशील विशेषताएं, जो अतिरिक्त कोड को कम करने में भी मदद करती हैं)।

रूबी के पास यह सब कुछ था:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

2

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


आप कई आंशिक तरीकों को दूसरी विधि के अंदर रख सकते हैं। उनके लिए किसी तरह का ऑटो-पैटर्न बनाना भ्रामक होगा।
मैथ्यू Whited

2

यह सरल है, यह छोटा है और यदि आप लाइन के नीचे संपत्ति के शरीर के अंदर एक वास्तविक कार्यान्वयन बनाना चाहते हैं, तो यह आपके प्रकार के बाहरी इंटरफ़ेस को नहीं तोड़ देगा।

इतना सरल है।


1

यहाँ एक बात ध्यान देने योग्य है, मेरी समझ में, यह सिर्फ # ३.० अंत पर होने वाली चीनी है, जिसका अर्थ है कि संकलक द्वारा उत्पन्न IL समान है। मैं काले जादू से बचने के बारे में सहमत हूं, लेकिन एक ही चीज के लिए सभी समान, कम लाइनें आमतौर पर एक अच्छी बात है।


1

मेरी राय में, आपको हमेशा सार्वजनिक क्षेत्रों के बजाय ऑटो-संपत्तियों का उपयोग करना चाहिए। उस ने कहा, यहाँ एक समझौता है:

एक आंतरिक क्षेत्र के साथ प्रारंभ करें जिसका नामकरण आप किसी संपत्ति के लिए उपयोग करेंगे। जब आप या तो पहले

  • इसकी विधानसभा के बाहर से क्षेत्र तक पहुंच की आवश्यकता है, या
  • एक गेटर / सेटर को तर्क संलग्न करने की आवश्यकता है

यह करो:

  1. फ़ील्ड का नाम बदलें
  2. इसे निजी बनाएं
  3. एक सार्वजनिक संपत्ति जोड़ें

आपके ग्राहक कोड को बदलने की आवश्यकता नहीं होगी।

किसी दिन, हालांकि, आपकी प्रणाली विकसित हो जाएगी और आप इसे अलग-अलग विधानसभाओं और कई समाधानों में विघटित करेंगे। जब ऐसा होता है, तो कोई भी उजागर फ़ील्ड आपको वापस लाने के लिए आएगा क्योंकि, जैसा कि जेफ़ ने उल्लेख किया है, सार्वजनिक क्षेत्र को सार्वजनिक संपत्ति में बदलना एक ब्रेकिंग एपीआई परिवर्तन है


0

मैं कोडरश का उपयोग करता हूं, यह ऑटो-प्रॉपर्टीज की तुलना में तेज है।

यह करने के लिए:

 private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

कुल आठ कीस्ट्रोक्स की आवश्यकता होती है।


5
अगर मैं CTRL और V दबाए रखता हूं, तो मैं बहुत सारे और बहुत सारे सामान पेस्ट कर सकता हूं, / वास्तव में जल्दी /, लेकिन यह इसे 'बेहतर' नहीं बनाता है। यह मूल प्रश्न का उत्तर कैसे देता है?
JBRWilkinson

0

कोड स्निपेट्स के साथ एक ही नाम की एक ऑटो-प्रॉपर्टी कुल सात कीस्ट्रोक्स होगी;)


0

@ महिला: मुझे नहीं मिला .. क्या आप ऑटो-संपत्तियों के साथ ऐसा नहीं कर सकते?

public string Title { get; }

या

public string Title { get; private set; }

क्या यह वही है जिसकी आप बात कर रहे हैं?


आप (उत्तरार्द्ध, पूर्व संकलन नहीं करेंगे) कर सकते हैं, लेकिन तब क्षेत्र आपकी वस्तु के अंदर अपरिवर्तनीय नहीं है।
डोमिनिक

सावधानी के शब्द, केवल संरचनाएं अपरिवर्तनीय होती हैं जब आसानी से ध्वजांकित किया जाता है, तो कक्षाएं बस अप्राप्य होती हैं।
ग्वेंटे

0

ऑटो-संपत्तियों के साथ मेरी सबसे बड़ी पकड़ यह है कि वे समय बचाने के लिए डिज़ाइन किए गए हैं लेकिन मुझे अक्सर लगता है कि मुझे बाद में पूर्ण विकसित गुणों में उनका विस्तार करना होगा।

क्या VS2008 गायब है एक विस्फोट ऑटो-संपत्ति रिफ्लेक्टर है।

हमारे पास एक इनकैप्सुलेट फील्ड रिफ्लेक्टर है जिस तरह से मैं सार्वजनिक क्षेत्रों का उपयोग करने के लिए जल्दी काम करता हूं।

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