स्थानीय चर को प्रारंभ करने की आवश्यकता क्यों होती है, लेकिन फ़ील्ड नहीं होते हैं?


140

अगर मैं अपनी कक्षा के भीतर एक बूल बनाता हूं, तो कुछ ऐसा ही है bool check, यह असत्य को परिभाषित करता है।

जब मैं अपनी विधि के भीतर एक ही बूल बनाता हूं, bool check(कक्षा के भीतर), तो मुझे एक त्रुटि "अनसाइनड लोकल वैरिएबल का उपयोग" मिल जाती है। क्यों?


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
मार्टिज़न पीटरर्स

14
प्रश्न अस्पष्ट है। क्या "क्योंकि विनिर्देश ऐसा कहता है" एक स्वीकार्य उत्तर होगा?
एरिक लिपर्ट

4
क्योंकि यह जावा में ऐसा ही किया गया था जब उन्होंने इसे कॉपी किया था। : पी
एल्विन थॉम्पसन

जवाबों:


177

युवल और डेविड के उत्तर मूल रूप से सही हैं; उपसंहार:

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

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

सबसे पहले, किसी भी चर के लिए, स्थानीय या अन्यथा, यह वास्तव में यह निर्धारित करना असंभव है कि एक चर सौंपा या अनसाइन किया गया है या नहीं। विचार करें:

bool x;
if (M()) x = true;
Console.WriteLine(x);

सवाल "एक्स सौंपा गया है?" "क्या M () सही है?" अब, मान लें कि यदि Fermat की अंतिम प्रमेय ग्यारहवें गजिलियन से कम है और अन्यथा झूठी है, तो सही है। यह निर्धारित करने के लिए कि क्या x निश्चित रूप से असाइन किया गया है, संकलक को अनिवार्य रूप से Fermat के अंतिम प्रमेय का प्रमाण प्रस्तुत करना होगा। कंपाइलर वह स्मार्ट नहीं है।

तो क्या संकलक स्थानीय लोगों के लिए बजाय करता औजार एक एल्गोरिथ्म जो है तेजी से , और overestimates जब एक स्थानीय निश्चित रूप से नहीं सौंपा गया है। यही है, इसमें कुछ गलत सकारात्मक हैं, जहां यह कहता है कि "मैं यह साबित नहीं कर सकता कि यह स्थानीय सौंपा गया है" भले ही आप और मैं जानते हैं कि यह है। उदाहरण के लिए:

bool x;
if (N() * 0 == 0) x = true;
Console.WriteLine(x);

मान लीजिए कि एन () एक पूर्णांक लौटाता है। आप और मैं जानते हैं कि N () * 0 0 होगा, लेकिन संकलक को यह पता नहीं है। (नोट: C # 2.0 संकलक को यह पता था , लेकिन मैंने उस अनुकूलन को हटा दिया, क्योंकि विनिर्देश यह नहीं कहता है कि संकलक है।)

सब ठीक है, तो हम अब तक क्या जानते हैं? स्थानीय लोगों के लिए एक सटीक उत्तर प्राप्त करना अव्यावहारिक है, लेकिन हम सस्ते में नॉट-असाइन-नेस को ओवरस्टाइट कर सकते हैं और एक बहुत अच्छा परिणाम प्राप्त कर सकते हैं जो "आपके अस्पष्ट कार्यक्रम को ठीक करता है" के पक्ष में गलतियां करता है। अच्छी बात है। खेतों के लिए एक ही चीज क्यों नहीं? यही है, एक निश्चित असाइनमेंट चेकर बनाओ जो सस्ते में overestimates?

खैर, एक स्थानीय के लिए आरंभिक रूप से कितने तरीके हैं? इसे विधि के पाठ के भीतर सौंपा जा सकता है। इसे विधि के पाठ में एक लंबोदर के भीतर सौंपा जा सकता है; हो सकता है कि लंबोदर को कभी आमंत्रित न किया जाए, इसलिए वे कार्य प्रासंगिक नहीं हैं। या इसे एकांत विधि के लिए "आउट" के रूप में पारित किया जा सकता है, जिस बिंदु पर हम यह मान सकते हैं कि जब यह विधि सामान्य रूप से वापस आती है। वे बहुत स्पष्ट बिंदु हैं जिन पर स्थानीय को सौंपा गया है, और वे उसी तरीके से वहीं हैं जो स्थानीय घोषित किया गया है । स्थानीय लोगों के लिए निश्चित असाइनमेंट निर्धारित करने के लिए केवल स्थानीय विश्लेषण की आवश्यकता होती है । तरीके कम होते हैं - एक विधि में कोड की एक लाख लाइनों से कम - और इसलिए पूरी विधि का विश्लेषण करना बहुत जल्दी है।

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

अनिवार्य रूप से एक क्षेत्र के लिए इनिशलाइज़र पूरे प्रोग्राम में कहीं भी हो सकता है , जिसमें वर्चुअल तरीके भी शामिल हैं जो उन पुस्तकालयों में घोषित किए जाएंगे जिनमें यह नहीं लिखा गया है :

// Library written by BarCorp
public abstract class Bar
{
    // Derived class is responsible for initializing x.
    protected int x;
    protected abstract void InitializeX(); 
    public void M() 
    { 
       InitializeX();
       Console.WriteLine(x); 
    }
}

क्या इस लाइब्रेरी को संकलित करना एक त्रुटि है? यदि हाँ, तो BarCorp बग को कैसे ठीक करना चाहिए? X को एक डिफ़ॉल्ट मान देकर? लेकिन यह है कि संकलक पहले से ही क्या करता है।

मान लीजिए यह पुस्तकालय कानूनी है। अगर फूकोर्प लिखते हैं

public class Foo : Bar
{
    protected override void InitializeX() { } 
}

क्या वह त्रुटि है? कंपाइलर को यह कैसे पता लगाना चाहिए? एकमात्र तरीका पूरे कार्यक्रम का विश्लेषण करना है जो प्रोग्राम के माध्यम से हर संभव पथ पर हर क्षेत्र के आरंभिक स्थैतिक को ट्रैक करता है , जिसमें ऐसे पथ शामिल हैं जिनमें रनटाइम पर वर्चुअल विधियों का विकल्प शामिल है । यह समस्या मनमाने ढंग से कठिन हो सकती है ; इसमें लाखों नियंत्रण पथों का अनुकरण किया जा सकता है। स्थानीय नियंत्रण प्रवाह का विश्लेषण माइक्रोसेकंड लेता है और विधि के आकार पर निर्भर करता है। वैश्विक नियंत्रण प्रवाह का विश्लेषण करने में घंटे लग सकते हैं क्योंकि यह कार्यक्रम और सभी पुस्तकालयों में हर पद्धति की जटिलता पर निर्भर करता है

तो एक सस्ता विश्लेषण क्यों न करें जो पूरे कार्यक्रम का विश्लेषण करने के लिए नहीं है, और बस और भी अधिक गंभीर रूप से overestimates? ठीक है, एक एल्गोरिथ्म का प्रस्ताव करें जो काम करता है जो सही प्रोग्राम लिखने के लिए बहुत कठिन नहीं है जो वास्तव में संकलित करता है, और डिजाइन टीम इस पर विचार कर सकती है। मुझे ऐसे किसी भी एल्गोरिथ्म का पता नहीं है।

अब, टिप्पणीकार का सुझाव है कि "एक निर्माता को सभी क्षेत्रों को इनिशियलाइज़ करना होगा"। यह एक बुरा विचार नहीं है। वास्तव में, यह ऐसा एक बुरा विचार है कि सी # में पहले से ही संरचना के लिए यह सुविधा है । Ctor के सामान्य रूप से वापस आने तक सभी क्षेत्रों को निश्चित रूप से असाइन करने के लिए एक स्ट्रक्चर कंस्ट्रक्टर की आवश्यकता होती है; डिफ़ॉल्ट कंस्ट्रक्टर सभी फ़ील्ड को उनके डिफ़ॉल्ट मानों पर आरंभ करता है।

कक्षाओं के बारे में क्या? वैसे, आप कैसे जानते हैं कि एक निर्माता ने एक क्षेत्र को इनिशियलाइज़ किया है ? Ctor खेतों को शुरू करने के लिए एक आभासी विधि कह सकता है , और अब हम उसी स्थिति में वापस आ गए हैं जैसे हम पहले थे। संरचनाएं व्युत्पन्न वर्ग नहीं हैं; कक्षाएं हो सकती हैं। क्या एक पुस्तकालय में एक अमूर्त वर्ग की आवश्यकता होती है जिसमें एक निर्माणकर्ता होता है जो अपने सभी क्षेत्रों को आरंभ करता है? अमूर्त वर्ग को कैसे पता चलता है कि खेतों को किन मूल्यों के आधार पर आरंभ किया जाना चाहिए?

जॉन का सुझाव है कि खेतों को शुरू करने से पहले एक कॉटर में कॉलिंग विधियों को प्रतिबंधित करें। तो, संक्षेप में, हमारे विकल्प हैं:

  • आम, सुरक्षित, अक्सर उपयोग किए जाने वाले प्रोग्रामिंग मुहावरों को अवैध बनाएं।
  • एक महंगा पूरे-कार्यक्रम का विश्लेषण करें जो संकलन को घंटों तक ले जाता है ताकि बग की तलाश हो सके।
  • डिफ़ॉल्ट मानों के लिए स्वत: प्रारंभ पर निर्भर है।

डिजाइन टीम ने तीसरा विकल्प चुना।


1
महान जवाब, हमेशा की तरह। हालांकि मेरा एक सवाल है: स्थानीय चर के साथ डिफ़ॉल्ट मानों को स्वचालित रूप से असाइन क्यों नहीं किया जाता है? दूसरे शब्दों में, क्यों एक विधि के अंदर भीbool x; समान नहीं होना चाहिए ? bool x = false;
डुर्रोन 597

8
@ durron597: क्योंकि अनुभव से पता चला है कि किसी स्थानीय को मान सौंपना भूलना शायद एक बग है। यदि इसकी शायद एक बग है और यह सस्ता और पता लगाने में आसान है, तो व्यवहार को अवैध या चेतावनी बनाने के लिए अच्छा प्रोत्साहन है।
एरिक लिपर्ट

27

जब मैं अपनी विधि के भीतर एक ही बूल बनाता हूं, तो बूल चेक (वर्ग के भीतर), मुझे एक त्रुटि "अनसाइनड लोकल वैरिएबल चेक का उपयोग" मिलती है। क्यों?

क्योंकि कंपाइलर आपको गलती करने से रोकने की कोशिश कर रहा है।

falseनिष्पादन के इस विशेष पथ में कुछ भी बदलने के लिए अपने चर को प्रारंभ करना क्या है ? शायद नहीं, विचार default(bool)करना वैसे भी गलत है, लेकिन यह आपको जागरूक होने के लिए मजबूर कर रहा है कि ऐसा हो रहा है। .NET वातावरण आपको "कचरा मेमोरी" तक पहुंचने से रोकता है, क्योंकि यह किसी भी मूल्य को उनके डिफ़ॉल्ट पर आरंभ करेगा। लेकिन फिर भी, कल्पना करें कि यह एक संदर्भ प्रकार था, और आप एक गैर-अशक्त की अपेक्षा विधि के लिए एक अनधिकृत (अशक्त) मान पारित करेंगे, और एक NRE प्राप्त करेंगे। कंपाइलर बस इसे रोकने की कोशिश कर रहा है, इस तथ्य को स्वीकार करते हुए कि यह कभी-कभी bool b = falseबयानों का परिणाम हो सकता है ।

एरिक लिपर्ट ने ब्लॉग पोस्ट में इस बारे में बात की :

हम इसे अवैध क्यों बनाना चाहते हैं, इसका कारण यह नहीं है, जैसा कि बहुत से लोग मानते हैं, क्योंकि स्थानीय चर कचरे के लिए शुरू होने वाला है और हम आपको कचरे से बचाना चाहते हैं। हम वास्तव में स्वचालित रूप से स्थानीय लोगों को उनके डिफ़ॉल्ट मानों से आरंभ करते हैं। (हालांकि C और C ++ प्रोग्रामिंग लैंग्वेज नहीं हैं, और आप आनंदपूर्वक आपको एक असिंचित लोकल से कचरा पढ़ने की अनुमति देंगे।) बल्कि, ऐसा इसलिए है क्योंकि इस तरह के कोड पाथ का अस्तित्व शायद एक बग है, और हम आपको फेंकना चाहते हैं। गुणवत्ता के गड्ढे; आपको उस बग को लिखने के लिए कड़ी मेहनत करनी चाहिए।

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


"कल्पना करें कि यह एक संदर्भ प्रकार था, और आप इस असंगठित वस्तु को एक प्रारंभिक एक की अपेक्षा विधि से पारित करेंगे" क्या आपका मतलब है: "कल्पना करें कि यह एक संदर्भ प्रकार था और आप डिफ़ॉल्ट (शून्य) के बजाय एक संदर्भ से गुजर रहे थे। वस्तु "?
डेडुप्लिकेटर

@ डेडप्लिकेटर हाँ। गैर-शून्य मान की अपेक्षा करने वाली विधि। उस हिस्से को संपादित किया। उम्मीद है कि अब यह स्पष्ट हो जाएगा।
युवल इट्ज़चकोव

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

इसके विपरीत: निष्पादन के विभिन्न रास्तों में घोषित और नियत मानों के द्वारा विधि के भीतर एक क्षेत्र हो सकता है। ऐसे अपवाद हो सकते हैं जो तब तक आसानी से हो सकते हैं जब तक कि आप किसी ऐसे फ्रेमवर्क के प्रलेखन में न देखें जो आप उपयोग कर सकते हैं या कोड के अन्य भागों में भी बनाए रख सकते हैं। यह निष्पादन का एक बहुत ही जटिल मार्ग पेश कर सकता है। इसलिए कंपाइलर संकेत देते हैं।
पीटर

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

25

स्थानीय चर को प्रारंभ करने की आवश्यकता क्यों होती है, लेकिन फ़ील्ड नहीं होते हैं?

संक्षिप्त उत्तर यह है कि असंवैधानिक स्थानीय चर तक पहुँचने वाले कोड को संकलक द्वारा विश्वसनीय विश्लेषण का उपयोग करके विश्वसनीय तरीके से पता लगाया जा सकता है। जबकि यह खेतों का मामला नहीं है। इसलिए संकलक पहले मामले को लागू करता है, लेकिन दूसरा नहीं।

स्थानीय चर को आरंभीकरण की आवश्यकता क्यों होती है?

यह सी # भाषा के एक डिजाइन निर्णय से अधिक नहीं है, जैसा कि एरिक लिपर्ट द्वारा समझाया गया है । CLR और .NET वातावरण को इसकी आवश्यकता नहीं है। उदाहरण के लिए, VB.NET, uninitialised स्थानीय चरों के साथ ठीक संकलित करेगा, और वास्तव में CLR डिफ़ॉल्ट रूप से मानों के लिए सभी uninitialised चर को प्रारंभ करता है।

वही C # के साथ हो सकता है, लेकिन भाषा डिजाइनरों ने नहीं चुना। कारण यह है कि आरंभिक चर बग का एक बहुत बड़ा स्रोत हैं और इसलिए, प्रारंभिककरण को अनिवार्य करके, संकलक आकस्मिक गलतियों पर कटौती करने में मदद करता है।

खेतों को आरंभीकरण की आवश्यकता क्यों नहीं है?

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

संग्रह प्रकारों के बारे में क्या?

स्थानीय चर आरंभीकरण का सी # प्रवर्तन सीमित है, जो अक्सर डेवलपर्स को बाहर करता है। कोड की निम्नलिखित चार पंक्तियों पर विचार करें:

string str;
var len1 = str.Length;
var array = new string[10];
var len2 = array[0].Length;

कोड की दूसरी पंक्ति संकलित नहीं होगी, क्योंकि यह एक असिंचित स्ट्रिंग चर को पढ़ने की कोशिश कर रहा है। कोड की चौथी पंक्ति हालांकि ठीक है, जैसा arrayकि आरंभीकृत किया गया है, लेकिन केवल डिफ़ॉल्ट मानों के साथ। चूंकि किसी स्ट्रिंग का डिफ़ॉल्ट मान शून्य है, इसलिए हमें रन-टाइम पर एक अपवाद मिलता है। जो कोई भी स्टैक ओवरफ्लो पर यहां समय बिताता है, उसे पता होगा कि यह स्पष्ट / अंतर्निहित प्रारंभिक असंगति एक महान कई "मुझे एक वस्तु के उदाहरण के लिए सेट नहीं" ऑब्जेक्ट संदर्भ क्यों मिल रहा है? " प्रशन।


"कंपाइलर स्थिर विश्लेषण का उपयोग यह निर्धारित करने के लिए नहीं कर सकता है कि क्या कोड के माध्यम से हर संभव पथ चर को हमारे सामने स्पष्ट रूप से आरंभ किया जा रहा है।" मुझे यकीन नहीं हुआ कि यह सच है। क्या आप ऐसे प्रोग्राम का उदाहरण पोस्ट कर सकते हैं जो स्थैतिक विश्लेषण के लिए प्रतिरोधी हो?
जॉन कुगेलमैन

@ जॉन कोहेलमैन, के सरल मामले public interface I1 { string str {get;set;} }और एक विधि पर विचार करें int f(I1 value) { return value.str.Length; }। यदि यह किसी लाइब्रेरी में मौजूद है, तो संकलक को यह पता नहीं चल सकता है कि वह लाइब्रेरी किससे जुड़ी होगी, इस प्रकार क्या setवसीयत को पहले बुलाया गया होगा get, बैकिंग फ़ील्ड को स्पष्ट रूप से प्रारंभ नहीं किया जा सकता है, लेकिन इसे ऐसे कोड को संकलित करना होगा।
डेविड अरनो

यह सच है, लेकिन मैं संकलन करते समय त्रुटि उत्पन्न होने की उम्मीद नहीं करूंगा f। यह निर्माणकर्ताओं को संकलित करते समय उत्पन्न होगा। यदि आप एक निर्माता को संभवतः एक क्षेत्र के साथ छोड़ देते हैं, तो यह एक त्रुटि होगी। सभी क्षेत्रों को शुरू करने से पहले क्लास के तरीकों और गेटर्स को कॉल करने पर भी प्रतिबंध लगाना पड़ सकता है।
जॉन कुगेलमैन

@JohnKugelman: मैं आपके द्वारा उठाए गए मुद्दे पर चर्चा करते हुए एक उत्तर दूंगा।
एरिक लिपर्ट

4
यह सही नहीं है। हम यहाँ असहमति की कोशिश कर रहे हैं!
जॉन कुगेलमैन

10

उपरोक्त अच्छे उत्तर, लेकिन मुझे लगा कि मैं लोगों के लिए एक बहुत ही सरल / छोटा उत्तर पोस्ट करूंगा ताकि एक लंबा (खुद की तरह) पढ़ने के लिए आलसी हो।

कक्षा

class Foo {
    private string Boo;
    public Foo() { /** bla bla bla **/ }
    public string DoSomething() { return Boo; }
}

निर्माणकर्ता में संपत्ति को आरम्भ किया Booजा सकता है या नहीं । इसलिए जब यह पाता है कि यह return Boo;नहीं माना जाता है कि यह आरंभीकृत किया गया है। यह बस त्रुटि को दबाता है।

समारोह

public string Foo() {
   string Boo;
   return Boo; // triggers error
}

{ }वर्ण कोड का एक खंड के क्षेत्र को परिभाषित। संकलक इन { }ब्लॉकों की शाखाओं को सामान का ट्रैक रखते हुए चलता है । यह आसानी से बता सकता है कि Booआरंभिक नहीं था। त्रुटि तब ट्रिगर होती है।

त्रुटि क्यों मौजूद है?

स्रोत कोड को सुरक्षित बनाने के लिए आवश्यक कोड की लाइनों की संख्या को कम करने के लिए त्रुटि पेश की गई थी। त्रुटि के बिना ऊपर इस तरह दिखेगा।

public string Foo() {
   string Boo;
   /* bla bla bla */
   if(Boo == null) {
      return "";
   }
   return Boo;
}

मैनुअल से:

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

संदर्भ: https://msdn.microsoft.com/en-us/library/4y7h161d.aspx

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.