दिलचस्प पोस्ट
एक पिक्सेल के एक्स, वाई एक छवि से रंग समन्वय कैसे प्राप्त करें? Apache HttpClient 4.0 में SSL प्रमाणपत्र त्रुटियों को कैसे अनदेखा करें सी में संघ के बारे में एक सवाल एंड्रॉइड बाइनरी फ़ाइल समस्याएं डाउनलोड करें मैं एंड्रॉइड में रूट एक्सेस का अनुरोध कैसे करूं? C # (.NET) के लिए हेडलेस ब्राउज़र? Mediastore से यूआरआइ से फाइल नाम और पथ प्राप्त करें जावास्क्रिप्ट का उपयोग करते हुए सीएसएस स्टाइलशीट को बदलना संभव है? (नहीं एक वस्तु की शैली, लेकिन स्टाइलशीट खुद) मान द्वारा मल्टी-आयामी सरणी को सॉर्ट करें मैं नवीनतम निर्भरता के लिए package.json में प्रत्येक निर्भरता को कैसे अपडेट कर सकता हूं? सफ़ल पाठ 2 लाइन अंत तय? अजगर मॉड्यूल का संस्करण कैसे जांच सकता है? निजी अंतिम स्थिर विशेषता बनाम निजी अंतिम विशेषता कर्सर का उपयोग किए बिना मैं SQL में चलने वाले कुल की गणना कैसे करूं? जावास्क्रिप्ट में ऑलमैन शैली के खतरनाक निहितार्थ

क्या ऑटो-कार्यान्वित गुणों के पीछे बैकिंग फ़ील्ड का उपयोग करना संभव है?

मुझे पता है कि मैं गुणों के लिए वर्बोज सिंटैक्स का उपयोग कर सकता हूं:

private string _postalCode; public string PostalCode { get { return _postalCode; } set { _postalCode = value; } } 

या मैं स्वत: कार्यान्वित गुणों का उपयोग कर सकते हैं

 public string PostalCode { get; set; } 

क्या मैं किसी तरह बैकिंग फ़ील्ड का उपयोग कर सकता हूं जो ऑटो-प्रचालित संपत्ति के पीछे है? (इस उदाहरण में यह होगा कि- postalCode )।


संपादित करें : मेरा प्रश्न डिजाइन के बारे में नहीं है, बल्कि इसके बारे में, मान लें, ऐसा करने की सैद्धांतिक क्षमता।

वेब के समाधान से एकत्रित समाधान "क्या ऑटो-कार्यान्वित गुणों के पीछे बैकिंग फ़ील्ड का उपयोग करना संभव है?"

मैं आपके बारे में नहीं जानता, लेकिन मैंने अन्य कंपनियों में परियोजनाओं में कोड लिखा है, और अब मुझे यह जानना चाहिए कि मैंने कुछ कैसे किया! इसलिए जवाब के लिए वेब खोज करने में आमतौर पर तेज़ है, और यह मुझे यहाँ लाया है

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

विकल्प उन चीजों को उजागर करना है जिन्हें हम नहीं देखना चाहते हैं, इसलिए हम उन्हें यूनिट का परीक्षण कर सकते हैं! हां, मैंने इसे वास्तविक जीवन के वातावरण में देखा है, और इसके बारे में अभी सोचने पर मुझे अपना सिर हिला दिया है।

इसलिए, मुझे उम्मीद है कि नीचे दिए गए कोड उपयोगी हो सकते हैं।

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

 private string _getBackingFieldName(string propertyName) { return string.Format("<{0}>k__BackingField", propertyName); } private FieldInfo _getBackingField(object obj, string propertyName) { return obj.GetType().GetField(_getBackingFieldName(propertyName), BindingFlags.Instance | BindingFlags.NonPublic); } 

मुझे नहीं पता कि आप किस सम्मेलन में काम करते हैं, लेकिन व्यक्तिगत रूप से, मैं निजी होने के लिए सहायक पद्धतियाँ पसंद करता हूं और एक लोअर केस पत्र के साथ शुरू होता है I मुझे पढ़ने में पर्याप्त स्पष्ट नहीं मिल रहा है, इसलिए मुझे पूर्ववर्ती अंडरस्कोर भी पसंद है।

बैकिंग फ़ील्ड की चर्चा है, और उनके स्वचालित नामकरण। यूनिट परीक्षणों के प्रयोजन के लिए, यदि आप बदल गए हैं या नहीं तो आपको बहुत तेज़ी से पता चल जाएगा! यह आपके वास्तविक कोड के लिए या तो, केवल परीक्षणों पर भयावह नहीं होगा। इसलिए हम नामों के नाम के बारे में सरल मान्यताओं को बना सकते हैं-जैसा कि ऊपर है आप असहमत हो सकते हैं, और यह ठीक है।

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

FieldInfo बारे में आसान काम यह है कि वे उन फ़ील्ड पर फ़ील्ड सेट कर सकते हैं जो FieldInfo मेल FieldInfo । यह उदाहरण के साथ बेहतर ढंग से समझाया गया है:

 var field = _getBackingField(myObjectToChange, "State"); field.SetValue(myObjectToChange, ObjectState.Active); 

इस स्थिति में, फ़ील्ड ObjectState नामक एक गणना प्रकार का है। निर्दोषों की सुरक्षा के उद्देश्य से नाम परिवर्तित कर दिए गए हैं! इसलिए, दूसरी पंक्ति में, आप देख सकते हैं कि FieldInfo तक पहुंचने से पहले वापस आ गया, मैं SetValue विधि पर कॉल कर सकता हूं, जिसे आपको लगता है कि पहले से आपके ऑब्जेक्ट से संबंधित होना चाहिए, लेकिन नहीं! यह प्रतिबिंब की FieldInfo एक फ़ील्ड को उस स्थान से अलग करता है, जहां से यह आया था, इसलिए आपको यह बता देना चाहिए कि किस उदाहरण को ( myObjectToChange ) के साथ कार्य करना चाहिए और इस प्रकार, जिस मान को आप चाहते हैं, इस मामले में, ObjectState.Active । सक्रिय

तो एक लंबी कहानी कम करने के लिए, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग हमें निजी क्षेत्रों तक पहुंचने और ऐसी स्थिति में बदतर होने से रोक देगी, जब कोड के डेवलपर का इरादा नहीं होता। कौन सा अच्छा है! यही वजह है कि सी # इतनी मूल्यवान है, और डेवलपर्स द्वारा पसंद किया गया है।

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

यह सीधे MSDN से आता है:

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

तो तुम नहीं कर सकते

दृश्य स्टूडियो 2010 में कम से कम, आप प्रतिबिंब का उपयोग कर एक वर्ग में निजी फ़ील्ड की सूची प्राप्त कर सकते हैं यदि आप स्पष्ट रूप से बताते हैं कि आप गैर-सार्वजनिक आवृत्ति फ़ील्ड चाहते हैं:

 FieldInfo[] myInfo = ClassWithPostalCode.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic); 

आप फिर FieldInfo सरणी के माध्यम से लूप कर सकते हैं इस मामले में आप देखेंगे कि बैकिंग फ़ील्ड का नाम शायद होगा

<PostalCode> k__BackingField

मैंने देखा है कि सभी स्वचालित गुण संपत्ति के नाम के पैटर्न को "k__BackingField" के बाद कोण कोष्ठक में अनुसरण करते हैं, लेकिन ध्यान रखें कि यह आधिकारिक नहीं है और भविष्य के संस्करणों में बदल सकता है। नेट मैं पूरी तरह से निश्चित नहीं हूं कि यह पिछले संस्करणों में अलग नहीं है, उस बात के लिए

एक बार जब आप क्षेत्र का नाम जानते हैं, तो आप इसका मूल्य इस तरह से प्राप्त कर सकते हैं:

 object oValue = obj.GetType().InvokeMember(fi.Name , BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance , null, obj, null); 

इस दस्तावेज़ से निम्नलिखित अंश देखें:

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

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

अद्यतनः https://github.com/jbevain/mono.reflection एक बैकिंग-फ़ील्ड रिज़ॉल्टर विधि के साथ आता है जो सी # द्वारा निर्मित ऑटो-प्रॉपर्टी के साथ काम करता है, VB.NET, और F #। NuGet पैकेज https://www.nuget.org/packages/Mono.Reflection/ पर है

मूल: मैं केवल सी # ऑटो-गुणों के लिए इस निष्पक्ष लचीली विधि के साथ समाप्त हुआ। चूंकि अन्य उत्तर स्पष्ट होते हैं, यह पोर्टेबल नहीं है और यदि काम करता है, तो कंपाइलर कार्यान्वयन <PropertyName>k__BackingField अलावा एक बैकिंग फ़ील्ड नामकरण योजना का उपयोग करता है जहां तक ​​मैंने देखा है, सी # संकलक के सभी कार्यान्वयन वर्तमान में इस नामकरण योजना का उपयोग करते हैं VB.NET और F # compilers एक और नामकरण योजना का उपयोग करते हैं जो इस कोड के साथ काम नहीं करेगा।

 private static FieldInfo GetBackingField(PropertyInfo pi) { if (!pi.CanRead || !pi.GetGetMethod(nonPublic:true).IsDefined(typeof(CompilerGeneratedAttribute), inherit:true)) return null; var backingField = pi.DeclaringType.GetField($"<{pi.Name}>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); if (backingField == null) return null; if (!backingField.IsDefined(typeof(CompilerGeneratedAttribute), inherit:true)) return null; return backingField; } 

नहीं, नहीं है। यदि आप बैकिंग फ़ील्ड का उपयोग करना चाहते हैं, तो ऑटो प्रॉपर्टी का उपयोग न करें और स्वयं को रोल करें

स्वत: लागू किए गए गुणों के लिए प्रलेखन से:

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

स्वत: कार्यान्वित गुण एक बैकिंग फ़ील्ड के साथ मैन्युअल रूप से कार्यान्वित संपत्ति के "लेजर" संस्करण हैं चूंकि वे किसी भी अतिरिक्त तर्क की अनुमति नहीं देते हैं, केवल एक चीज जिसे आप उनके साथ कर सकते हैं वह "छिपा हुआ" निजी क्षेत्र को पढ़ या लिखना है। अगर आप अपने निजी तरीकों को इस विशेषाधिकार प्राप्त करना चाहते हैं, तो आप किसी एक एक्सेसर तक पहुंच को सीमित करने के लिए private निधि का उपयोग कर सकते हैं (आमतौर पर, set उस मामले में निजी होगा)।

यदि आप कुछ अन्य वर्ग निजी क्षेत्रों (जैसे बीसीएल से एक वर्ग) तक पहुंचना चाहते हैं, तो आप इसे करने के लिए प्रतिबिंब का उपयोग कर सकते हैं (जैसा कि इन उदाहरणों में बताया गया है), लेकिन यह एक बुरा हैक होगा जहां कोई भी गारंटी नहीं दे सकता है कि कोई एक फ़्रेमवर्क के स्रोत में -letter परिवर्तन भविष्य में आपका कोड नहीं तोड़ देगा।

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

उल्लेख नहीं कि कंपाइलर प्रत्येक कॉल को सबसे ज्यादा लिखेगा, इसलिए कोई प्रदर्शन अंतर नहीं है।