2013-08-24 5 views
6

मुझे लगता है समझाने के लिए सबसे आसान तरीका है एक काल्पनिक उदाहरण के द्वारा होता है:को संभालने के लिए कैसे "नहीं सभी कोड पथ मान" जब समारोह के तर्क एक वापसी सुनिश्चित करता

public static int Fail() { 
    var b = true; 
    if (b) { 
     return 0; 
    } 
} 

इस कोड संकलन नहीं होगा , और त्रुटि देता है "सभी कोड पथ एक मूल्य वापस नहीं करते हैं," जबकि हम मनुष्य स्पष्ट रूप से देख सकते हैं कि यह करता है। मैं समझता हूं क्यों। मेरा सवाल यह है कि स्थिति का समाधान करने के लिए क्या किया जाना चाहिए। यह कुछ ऐसा हो सकता है:

public static int Fail() { 
    var b = true; 
    if (b) { 
     return 0; 
    } 
    throw new ApplicationException("This code is unreachable... but here we are."); 
} 

लेकिन यह सब सिर्फ मूर्खतापूर्ण लगता है। क्या कोई बेहतर तरीका है? दोबारा, यह कोड एक समेकित उदाहरण है (और इसे return 0 तक घटाया जा सकता है)। मेरा वास्तविक कोड विशाल और जटिल है, लेकिन तार्किक रूप से (गणितीय सबूत द्वारा) बाहर निकलने का प्रयास करने से पहले एक मूल्य वापस कर देता है।

+0

ध्यान दें कि यदि आप बी को 'कॉन्स' स्थानीय चर ('कॉन्स्ट बूल बी = सत्य;') के रूप में घोषित करते हैं, तो यह ठीक –

+1

संकलित करता है यदि आपकी विधि इतनी "भारी और जटिल" है तो आपको शायद इसे पुन: सक्रिय करना चाहिए। अगले मानव प्रोग्रामर के पास क्या उम्मीद होगी यदि कोई संकलक इसे छोड़ देता है? – lesscode

+1

https://github.com/coder0xff/parlex/blob/master/IDE/Nfa.cs Kameda-Weiner एल्गोरिदम पर आधारित है " नोडेटर्मिनिस्टिक फिनिट ऑटोमाटा के राज्य न्यूनीकरण पर"। यह सामान मानव प्रोग्रामर के लिए नहीं है। – Brent

उत्तर

8

सी # कोड प्रवाह विश्लेषण सीमित है और आपके नमूना बिंदुओं के अनुसार ऐसे मामले हैं जहां सभी पथ वापस आते हैं लेकिन संकलक इसे पहचान नहीं सकते हैं। अपवाद फेंकना उन परिस्थितियों में एक स्वीकार्य उपाय है।

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

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

+0

रिफैक्टरिंग मेरी पहली वृत्ति भी है। दुर्भाग्यवश, इस मामले में (एनएफए न्यूनतमकरण), समस्या अव्यवहार्य है (गणितीय अर्थ में) और यह वास्तव में नहीं किया जा सकता है। मैं एक लूप के माध्यम से जा रहा हूं, कुछ स्थितियों का परीक्षण कर रहा हूं, जिनमें से मुझे पता है कि कम से कम एक परिणाम के रूप में उपयोग किया जाएगा। – Brent

+0

मैंने फैसला किया है, कुछ दिनों के बाद, मुझे आपका जवाब सबसे अच्छा लगता है, और इसे आपके लिए स्विच कर दिया गया है। मैं हालांकि पूछना चाहता हूं, मैं किस अपवाद को फेंक दूं? मैं 'TheAssumptionsMadeAboutThisProgramsLogicAreIncorrectException' बना सकता था, लेकिन जैसा कि मैंने कहा, यह सब कुछ मूर्खतापूर्ण लगता है। – Brent

+0

@ ब्रेंट व्यक्तिगत रूप से मैं केवल 'सिस्टम.एक्सप्शन' का उपयोग करता हूं लेकिन गलत होने के बारे में एक बहुत ही विशिष्ट संदेश में जोड़ता हूं। – JaredPar

1

कंपाइलर जटिल गणितीय प्रक्रियाओं को निष्पादित नहीं करता है ताकि आप एक मूल्य वापस कर सकें, यह उस संबंध में अपेक्षाकृत गूंगा जानवर है।

यदि आप अपनी धारणाओं के बारे में निश्चित हैं, तो अंत में return 0; जोड़ें, वास्तविकता बताते हुए एक टिप्पणी के साथ, यह कभी नहीं पहुंचाया जाएगा।

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

+0

जेरेडपार के जवाब पर मेरी टिप्पणी देखें। हालांकि, मुझे लगता है कि मुझे आपके साथ सहमत होना होगा। एक वापसी वापसी; // यह कोड पहुंच योग्य नहीं है 'सबसे अच्छी चीज की तरह लगता है। – Brent

+0

पक्सडीब्लो सही है, सही तरीका वह है जो उसने कहा था। लेकिन अगर यह आपको खुश कर देगा;), आप मिन्हफा को फोरैच के बाहर परिभाषित कर सकते हैं, फिर बस तोड़ दें, और आखिर में फ्रोच के बाद मिनीफा को वापस कर दें। (यहां आपके कोड के आधार पर: https://github.com/coder0xff/parlex/blob/master/IDE/Nfa.cs) – MNZ

+0

@MNZ क्या आप यह स्पष्ट कर सकते हैं कि यह कैसे किया जाएगा? जहां तक ​​मैं कह सकता हूं, यह रोकथाम की समस्या का निर्णय लेने के लिए समान है। इसके अलावा, आपके द्वारा वर्णित 'मिनीफा' दृष्टिकोण के आधार पर, मुझे अभी भी minnfa को शून्य में प्रारंभ करना होगा, क्योंकि संकलक अभी भी निर्णय लेता है कि foreach अपना मान निर्धारित नहीं कर सकता है। – Brent

0

आम तौर पर प्रोग्रामर की कक्षाओं के एक जोड़े हैं:

  1. जो सब कुछ खत्म हो लौट वे।
  2. वे जो केवल एक funcion/विधि के अंत में वापस आते हैं।

पहले दृष्टिकोण:

public static int Fail() { 
    var b = true; 
    if (b) 
    return 0; 

    return 1; 
} 

मैं आमतौर पर दूसरा दृष्टिकोण पसंद करते हैं, क्योंकि यह आसान है जल्दी से जहां देखने के लिए एक समारोह/विधि रिटर्न।

public static int Fail() { 
    var b = true; 
    var returnValue = 1: 
    if (b) 
    returnValue = 0; 

    return returnValue; 
} 
1

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

0

सच देर जवाब है, लेकिन मैं एक परिदृश्य है, जिसमें समारोह क्या वापस जाने के लिए पता नहीं होगा कल्पना कर सकते हैं: डिबगर

2) चरण var b = true; से अधिक

का उपयोग कर

1) चरण दर चरण भागो

3) जब if (b) { पहुंच गया है, तो घड़ी में b = false डाल दें। यह दोनों false लौट सकते हैं और b = false

4 आवंटित) (if से अधिक पर कदम होगा)

5) समारोह की समाप्ति तक पहुँच जाता है, कोई वापसी वहाँ

है इस दृष्टिकोण से, return स्पष्ट रूप से की जरूरत है।

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