वेबिनार जॉन स्कीट इंस्पेक्ट्स रेस्परर को देखने के बाद , मैंने पुनरावर्ती रचनाकार कॉल के साथ थोड़ा खेलना शुरू कर दिया है और पाया है, कि निम्न कोड मान्य सी # कोड है (मान्य से मेरा मतलब है कि यह संकलित है)।
class Foo
{
int a = null;
int b = AppDomain.CurrentDomain;
int c = "string to int";
int d = NonExistingMethod();
int e = Invalid<Method>Name<<Indeeed();
Foo() :this(0) { }
Foo(int v) :this() { }
}
जैसा कि हम सभी जानते हैं, कंपाइलर द्वारा फील्ड इनिशियलाइज़ेशन को कंस्ट्रक्टर में ले जाया जाता है। इसलिए यदि आपके पास एक क्षेत्र जैसा है int a = 42;, तो आपके पास सभी निर्माणकर्ताओं a = 42में होगा । लेकिन अगर आपके पास कंस्ट्रक्टर एक और कंस्ट्रक्टर को बुला रहा है, तो आपके पास केवल एक में इनिशियलाइज़ेशन कोड होगा।
उदाहरण के लिए यदि आपके पास डिफॉल्ट कंस्ट्रक्टर को कॉल करने वाले मापदंडों के साथ कंस्ट्रक्टर है, तो आपके पास a = 42केवल डिफॉल्ट कंस्ट्रक्टर में असाइनमेंट होगा ।
दूसरे मामले का वर्णन करने के लिए, अगला कोड:
class Foo
{
int a = 42;
Foo() :this(60) { }
Foo(int v) { }
}
में संकलित:
internal class Foo
{
private int a;
private Foo()
{
this.ctor(60);
}
private Foo(int v)
{
this.a = 42;
base.ctor();
}
}
इसलिए मुख्य मुद्दा यह है कि इस प्रश्न के प्रारंभ में दिया गया मेरा कोड निम्नलिखित में संकलित है:
internal class Foo
{
private int a;
private int b;
private int c;
private int d;
private int e;
private Foo()
{
this.ctor(0);
}
private Foo(int v)
{
this.ctor();
}
}
जैसा कि आप देख सकते हैं, संकलक तय नहीं कर सकता है कि फ़ील्ड इनिशियलाइज़ेशन कहाँ रखा जाए और, परिणामस्वरूप, इसे कहीं भी नहीं रखा जाए। यह भी ध्यान दें, कोई baseरचनाकार कॉल नहीं है। बेशक, कोई भी वस्तु नहीं बनाई जा सकती है, और आप हमेशा के लिए समाप्त StackOverflowExceptionहो जाएंगे यदि आप एक उदाहरण बनाने की कोशिश करेंगे Foo।
मेरे दो सवाल हैं:
कंपाइलर पुनरावर्ती निर्माता को कॉल की अनुमति क्यों देता है?
हम खेतों के लिए संकलक के ऐसे व्यवहार का निरीक्षण क्यों करते हैं, इस तरह के वर्ग के भीतर आरम्भ में?
कुछ नोट: ReSharper आपको चेतावनी देता है Possible cyclic constructor calls। इसके अलावा, जावा में इस तरह के कंस्ट्रक्टर कॉल का संकलन नहीं होगा, इसलिए जावा कंपाइलर इस परिदृश्य में अधिक प्रतिबंधक है (जॉन ने वेबिनार में इस जानकारी का उल्लेख किया है)।
यह इन सवालों को अधिक दिलचस्प बनाता है, क्योंकि जावा समुदाय के सभी सम्मान के साथ, सी # संकलक कम से कम अधिक आधुनिक है।
यह C # 4.0 और C # 5.0 संकलक का उपयोग करके संकलित किया गया था और dotPeek का उपयोग करके विघटित किया गया था ।