2011-05-25 11 views
48

संभव डुप्लिकेट:
Cannot use ‘this’ in member initializer?सदस्य प्रारंभकर्ताओं में आप 'इस' का उपयोग क्यों नहीं कर सकते?

कोई भी विचार कारण है कि मैं कोई त्रुटि मिलती है अगर मैं कुछ इस तरह से करने की कोशिश:

public class Bar 
{ 
    public Bar(Foo foo) 
    { 
    } 
} 

public class Foo 
{ 
    private Bar _bar = new Bar(this); 
} 

मैं कह कोई त्रुटि मिलती है:

सदस्य प्रारंभकर्ता में "इसका उपयोग नहीं कर सकता"

लेकिन निम्न काम करता है:

public class Foo 
{ 
    private Bar _bar; 

    public Foo() 
    { 
     _bar = new Bar(this); 
    } 
} 

कोई भी इस के पीछे कारण पता है? मेरी समझ यह थी कि ये एक ही आईएल को संकलित करेंगे, इसलिए उत्सुक हूं कि किसी को अनुमति क्यों है और दूसरा नहीं है।

धन्यवाद, एलेक्स

+0

मुझे यकीन नहीं है कि यह प्रश्न डुप्लिकेट के रूप में क्यों बंद है, क्योंकि दूसरे प्रश्न का उत्तर यह है कि क्यों एक त्रुटि के रूप में रिपोर्ट नहीं की जा रही थी, "यह संकलक में एक बग है" वास्तव में बिना समझाओ कि इसकी अनुमति क्यों नहीं थी। – Powerlord

उत्तर

52

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

एनोटेट कल्पना कुछ भी जब मैं उसके बगल में पास कर रहा हूँ इस बारे में क्या कहना है कि क्या जांच करेगा ..

संपादित करें: सी # 4 एनोटेटेड स्पेक में कोई स्पष्टीकरण नहीं है। बस (10.5.5.2 में):

एक उदाहरण फ़ील्ड के लिए एक परिवर्तनीय प्रारंभकर्ता उदाहरण के संदर्भ का संदर्भ नहीं दे सकता है।

+0

दिलचस्प, धन्यवाद। कभी एहसास नहीं हुआ कि परिवर्तनीय प्रारंभकर्ता बेस क्लास ctor से पहले भाग गए ... – AlexC

+19

आप निश्चित रूप से सही हैं। हमें एनोटेटेड स्पेस के अगले संस्करण में इसे जोड़ना चाहिए, यह एक अच्छा है। –

+1

मेरे बैकिंग फ़ील्ड को 'Lazy' –

13

फ़ील्ड प्रारंभकर्ता बेस क्लास कन्स्ट्रक्टर से पहले चलाते हैं तो this अभी तक मौजूद नहीं है। यह केवल एक बार बेस कन्स्ट्रक्टर निष्पादित करने के बाद ही मौजूद है।

17.10.2 Instance variable initializers:

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

+1

में परिवर्तित करने के वीएस सुझाव चला गया है वैसे यह मौजूद है - यह अभी तक पूरी तरह से प्रारंभ नहीं हुआ है। –

0

मेरा मानना ​​है कि इस वजह से खेतों को प्रारंभ करने से पहले वर्ग तो initializes जब निम्न कोड चलता है:

private Bar _bar = new Bar(this); 

"इस" कोई वास्तविक मूल्य संदर्भित किया जाना है।

हालांकि यह निर्माता में डालने का मतलब है "फू" referencable का एक उदाहरण द्वारा "इस"

0

सी # में होता है, कोई तर्क बाहर तरीकों 'और गुण के शरीर में किया जाता है।

फील्ड प्रारंभकर्ता एक अपवाद हैं, लेकिन कुछ सीमाओं के साथ।

यह इस कीवर्ड के साथ मौजूदा वस्तु का एक संदर्भ हो रही है क्योंकि एक वर्ग क्षेत्र घोषणा, तर्क लेकिन वर्ग डिजाइन नहीं है, जबकि इस रन-टाइम अर्थ विज्ञान का हिस्सा है गलत चाहते।

वैसे, ऐसा लगता है कि यह एक सी # डिज़ाइन निर्णय, है, क्योंकि वास्तव में, एक क्षेत्र प्रारंभकर्ता वर्ग निर्माण के दौरान चलाता है, तो "वर्ग की घोषणा की वर्तमान उदाहरण" इस के माध्यम से उपलब्ध होना चाहिए। लेकिन फिर, एक विधि या संपत्ति निकाय के बाहर क्या होगा?

जॉन स्कीट और अन्य ने इंगित किया, यह उपलब्ध नहीं है क्योंकि बेस कन्स्ट्रक्टर निष्पादन के बाद फील्ड प्रारंभकर्ता निष्पादित किए जाते हैं।

+0

किसी विधि या प्रॉपर्टी बॉडी के बाहर, यह तब भी ऑब्जेक्ट होगा जिसका संदर्भ कोड निष्पादित कर रहा था। यह सदस्य प्रारंभकर्ताओं के लिए इसे अनुमति देने के लिए सही * भावना * बना देगा - इसमें केवल समस्याएं होंगी यदि उसने राज्य का उपयोग करने की कोशिश की जो अभी तक बेस क्लास द्वारा शुरू नहीं किया गया था। –

+0

पूरी तरह से सहमत हुए और टिप्पणी के लिए धन्यवाद। यही कारण है कि मैं इस तथ्य को इंगित करता हूं कि यह एक सी # डिजाइन निर्णय है, लेकिन मैं सवाल पूछता हूं क्योंकि मुझे इस दायरे में ** यह ** कीवर्ड होने में भ्रमित लगता है (यह आसानी से पूरी त्रुटियों में हो सकता है)। –

+0

आईएएस: लेकिन ध्यान दें कि * छोटे * परिवर्तन के साथ सी # को जावा की तरह अधिक कार्य करने के लिए (जहां सुपरक्लस कन्स्ट्रक्टर को चर प्रारंभकर्ताओं से पहले निष्पादित किया जाता है) जिससे त्रुटियों का कारण दूर हो जाता है। मुझे लगता है * मौलिक रूप से * यह समझ में आता है - यह सिर्फ कुछ चेतावनी है। –

0

सदस्य प्रारंभकर्ता कक्षा निर्माणकर्ता से पहले भागते हैं। ध्यान दें कि आपके पास एक ही कक्षा में कई सदस्य प्रारंभकर्ता हो सकते हैं।

यदि आप कन्स्ट्रक्टर में 'यह' का उपयोग करते हैं -> प्रारंभकर्ताओं के साथ सभी सदस्यों को प्रारंभ किया गया था। तो सब कुछ ठीक है।

यदि आप सदस्य प्रारंभकर्ता में 'यह' का उपयोग करते हैं: अन्य सदस्यों (प्रारंभकर्ताओं के साथ संलग्न) अभी तक प्रारंभ नहीं किए जा सकते हैं -> 'यह' अभी तक तैयार नहीं है। यही कारण है कि 'इस' का उपयोग करने की अनुमति नहीं है यहां अनुमति नहीं है।

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