2011-01-05 20 views
31

आप सिंटैक्स का उपयोग निर्माता कॉल श्रृंखला हैं:निर्माता श्रृंखलन आदेश

public frmConfirm(): this(1) 

जब अतिभारित निर्माता कहा जाता है? साथ ही, क्या कोई पुष्टि कर सकता है कि यदि कक्षा एक रूप है, तो दोनों रचनाकारों में InitializeComponent() कॉल होने से समस्याएं उत्पन्न होंगी?

+5

@ madmik3: यह सुनिश्चित करने के लिए कोड लिखना आसान है कि क्या होता है। सवाल यह है कि क्या सभी परिस्थितियों में होने वाली * गारंटी * है (अलग-अलग ओएस, सीएलआर के विभिन्न संस्करण)। –

+0

एक संबंधित पोस्ट - [सी # कन्स्ट्रक्टर निष्पादन आदेश] (https://stackoverflow.com/q/1882692/465053)। – RBT

उत्तर

42

जंजीर कन्स्ट्रक्टर को परिभाषित कन्स्ट्रक्टर के शरीर से तुरंत पहले बुलाया जाएगा। उत्पन्न आईएल अनुक्रम अन्य निर्माता के लिए तत्काल call है, इसके बाद आईएल द्वारा कन्स्ट्रक्टर में बयान से उत्पन्न किया गया है।

तो यदि आप किसी अन्य निर्माता को चेन करते हैं और उस कन्स्ट्रक्टर InitializeComponent() पर कॉल करता है तो कॉलिंग कन्स्ट्रक्टर को इस विधि को कॉल नहीं करना चाहिए।

उदाहरण के लिए

, इस नमूने वर्ग दिया: कि कोई आर्ग निर्माता बी क्षेत्र के लिए 2 असाइन करने से पहले अन्य निर्माता कॉल

.class private auto ansi beforefieldinit Foo 
     extends [mscorlib]System.Object 
    { 
    .field public int32 A 
    .field public int32 B 

    // method line 1 
    .method public hidebysig specialname rtspecialname 
      instance default void '.ctor'() cil managed 
    { 
     .maxstack 8 
     IL_0000: ldarg.0 
     IL_0001: ldc.i4.1 
     IL_0002: call instance void class Foo::'.ctor'(int32) 
     IL_0007: ldarg.0 
     IL_0008: ldc.i4.2 
     IL_0009: stfld int32 Foo::B 
     IL_000e: ret 
    } // end of method Foo::.ctor 

    // method line 2 
    .method public hidebysig specialname rtspecialname 
      instance default void '.ctor' (int32 a) cil managed 
    { 
     .maxstack 8 
     IL_0000: ldarg.0 
     IL_0001: call instance void object::'.ctor'() 
     IL_0006: ldarg.0 
     IL_0007: ldarg.1 
     IL_0008: stfld int32 Foo::A 
     IL_000d: ret 
    } // end of method Foo::.ctor 

    } // end of class Foo 

नोट:

class Foo { 
    public int A, B; 

    public Foo() : this(1) { 
     B = 2; 
    } 

    public Foo(int a) { 
     A = a; 
    } 
} 

यह उत्पन्न आईएल है ।

+0

बिल्कुल सही। मैंने यही सोचा, धन्यवाद – JeffE

+0

क्या एमएसआईएल एक परिपत्र संदर्भ नहीं देगा? (मुझे पता है कि यह नहीं होगा लेकिन मुझे समझ में नहीं आ रहा है क्यों) ऐसा लगता है .क्टर() कॉल कर रहा है .क्टर (int32 ए) और इसके विपरीत।क्या कोई स्पष्टीकरण दे सकता है कि यह क्यों नहीं हो रहा है? – arviman

+3

@arviman 'foo: .ctor()' 'Foo: .ctor (int32) 'को कॉल कर रहा है, लेकिन बदले में' System.Object: .ctor()', *** *** *** नहीं है। ctor() '। – cdhowie

9

this(1) निर्माता को पहले कहा जाता है।

जहां तक ​​आपका दूसरा प्रश्न है, InitializeComponent और फॉर्म विरासत के साथ अन्य मुद्दों के कारण, मैं सुझाव दूंगा कि आप विरासत की बजाय संरचना का उपयोग करें।

+0

मुझे फॉर्म विरासत के साथ कुछ मुद्दों के बारे में पता है, लेकिन यह मेरे प्रोजेक्ट – JeffE

5

इस तरह के प्रश्न पर उत्तर देखने के लिए स्थान C# Language Specification है। (मेरा जोर है) अनुभाग 10.11.1 में, निर्माता initializers आप पढ़ सकते हैं:

सभी उदाहरण कंस्ट्रक्टर्स ( वर्ग वस्तु के अलावा किन्हीं) परोक्ष एक और उदाहरण निर्माता की एक मंगलाचरण तुरंत से पहले शामिल कन्स्ट्रक्टर-बॉडी।

अतिरिक्त पठन पता चलता है कि:

  • अगर निर्माता प्रपत्र base(arguments) का एक उदाहरण निर्माता प्रारंभकर्ता है, प्रत्यक्ष आधार वर्ग से एक निर्माता सक्रिय किया जाएगा।
  • यदि निर्माता के पास फॉर्म this(argument) का एक उदाहरण कन्स्ट्रक्टर प्रारंभकर्ता है, तो कक्षा में एक निर्माता स्वयं ही लागू किया जाएगा।
  • यदि कोई इंस्टेंस कन्स्ट्रक्टर प्रारंभकर्ता प्रदान नहीं किया गया है, तो base() स्वचालित रूप से जोड़ा जाएगा।
+0

के लिए सबसे अच्छा समाधान है मेरे ध्यान में सी # भाषा विनिर्देश लाने के लिए धन्यवाद – Ronnie

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