TLDR: यह लंबे समय से चली आ रही एक ज्ञात बग है। मैंने पहली बार इसके बारे में 2010 में लिखा था:
https://blogs.msdn.microsoft.com/ericlippert/2010/01/18/a-definite-assignment-anomaly/
यह हानिरहित है और आप इसे सुरक्षित रूप से अनदेखा कर सकते हैं, और कुछ हद तक अस्पष्ट बग खोजने के लिए खुद को बधाई दे सकते हैं।
संकलक लागू क्यों नहीं करता है Emailजिसे निश्चित रूप से सौंपा जाना चाहिए?
ओह, यह एक फैशन में है। यह सिर्फ एक गलत विचार है कि किस स्थिति का अर्थ है कि चर निश्चित रूप से सौंपा गया है, जैसा कि हम देखेंगे।
यदि यह संरचना अलग असेंबली में बनाई गई है, तो यह कोड क्यों संकलित करता है, लेकिन यदि मौजूदा असेंबली में संरचना को परिभाषित किया गया है तो यह संकलन नहीं करता है?
यह बग की जड़ है। बग एक अंतर का परिणाम है कि C # कंपाइलर स्ट्रक्चर्स पर निश्चित असाइनमेंट चेक करता है और कंपाइलर मेटाडेटा को पुस्तकालयों से कैसे लोड करता है।
इस पर विचार करो:
struct Foo
{
public int x;
public int y;
}
// Yes, public fields are bad, but this is just
// to illustrate the situation.
void M(out Foo f)
{
ठीक है, इस बिंदु पर हम क्या जानते हैं? fप्रकार के एक चर के लिए एक उपनाम है Foo, इसलिए भंडारण पहले से ही आवंटित किया गया है और निश्चित रूप से कम से कम राज्य में है कि यह भंडारण आवंटन से बाहर आ गया। यदि कॉल करने वाले द्वारा चर में कोई मान रखा गया था, तो वह मान है।
हमें क्या चाहिए? हमें आवश्यक है कि fनिश्चित रूप से किसी भी बिंदु पर नियत किया जाए जहां नियंत्रण Mसामान्य रूप से रहता है। तो आप कुछ इस तरह की उम्मीद करेंगे:
void M(out Foo f)
{
f = new Foo();
}
जो सेट f.xऔर f.yउनके डिफ़ॉल्ट मानों के लिए। लेकिन इससे क्या?
void M(out Foo f)
{
f = new Foo();
f.x = 123;
f.y = 456;
}
वह भी ठीक होना चाहिए। लेकिन, और यहां किकर है, हमें केवल एक पल बाद उन्हें उड़ाने के लिए डिफ़ॉल्ट मानों को असाइन करने की आवश्यकता क्यों है? यह देखने के लिए कि हर क्षेत्र सौंपा गया है, सी # निश्चित असाइनमेंट चेकर चेक ! यह कानूनी है:
void M(out Foo f)
{
f.x = 123;
f.y = 456;
}
और वह कानूनी क्यों न हो? यह एक मूल्य प्रकार है। fएक चर है, और इसमें पहले से ही एक मान्य मान शामिल है Foo, तो चलो बस खेतों को सेट करें, और हम कर रहे हैं, है ना?
सही। तो क्या बग है?
बग जो आपने खोजा है वह है: लागत बचत के रूप में, सी # संकलक उन निजी क्षेत्रों के लिए मेटाडेटा लोड नहीं करता है जो संदर्भित पुस्तकालयों में हैं । यह मेटाडेटा बहुत बड़ा हो सकता है , और यह बहुत कम जीत के लिए कंपाइलर को धीमा कर देगा ताकि यह हर बार मेमोरी में लोड हो सके।
और अब आपको आपके द्वारा पाए गए बग के कारण को कम करने में सक्षम होना चाहिए। जब कंपाइलर यह देखने के लिए जाँच करता है कि क्या आउट पैरामीटर निश्चित रूप से असाइन किया गया है, तो यह ज्ञात फ़ील्ड की संख्या की तुलना उन फ़ील्ड्स की संख्या से करता है जो निश्चित रूप से आरंभिक थे और आपके मामले में यह केवल शून्य सार्वजनिक फ़ील्ड के बारे में जानता है क्योंकि निजी फ़ील्ड मेटाडेटा लोड नहीं किया गया था । संकलक का निष्कर्ष है "शून्य क्षेत्र आवश्यक, शून्य क्षेत्र आरंभीकृत, हम अच्छे हैं।"
जैसा कि मैंने कहा, यह बग एक दशक से अधिक समय से है और आप जैसे लोग कभी-कभार इसे खोज लेते हैं और इसकी रिपोर्ट करते हैं। यह हानिरहित है, और इसे ठीक करने की संभावना नहीं है क्योंकि इसे ठीक करना लगभग शून्य लाभ है लेकिन एक बड़ी प्रदर्शन लागत है।
और निश्चित रूप से बग उन स्ट्रक्चर्स के निजी क्षेत्रों के लिए रिप्रो नहीं करता है जो आपके प्रोजेक्ट में स्रोत कोड में हैं, क्योंकि जाहिर है कंपाइलर के पास पहले से ही निजी क्षेत्रों के बारे में जानकारी है।