मैं अलोकप्रिय होने जा रहा हूं और कहता हूं हां, यह बुरा है। यदि आपके कोड की कार्यक्षमता सशर्त तर्क को लागू करने के लिए उस पर निर्भर है।
अर्थात
if(quickLogicA && slowLogicB) {doSomething();}
अच्छा है, लेकिन
if(logicA && doSomething()) {andAlsoDoSomethingElse();}
बुरा है, और निश्चित रूप से कोई भी इससे सहमत नहीं होगा ?!
if(doSomething() || somethingElseIfItFailed() && anotherThingIfEitherWorked() & andAlwaysThisThing())
{/* do nothing */}
तर्क:
यदि दोनों पक्षों का मूल्यांकन केवल तर्क नहीं करने के बजाय आपका कोड त्रुटियां हैं। यह तर्क दिया गया है कि यह कोई समस्या नहीं है, 'और' ऑपरेटर को c # में परिभाषित किया गया है, इसलिए अर्थ स्पष्ट है। हालांकि, मैं तर्क देता हूं कि यह सच नहीं है।
कारण 1. ऐतिहासिक
अनिवार्य रूप से आप अपने कोड में कार्यक्षमता प्रदान करने के लिए एक कंपाइलर ऑप्टिमाइज़ेशन (जो मूल रूप से इरादा था) पर भरोसा कर रहे हैं।
हालांकि c # में भाषा विनिर्देश बूलियन की गारंटी देता है 'और' ऑपरेटर लघु परिचलन करता है। यह सभी भाषाओं और संकलक के लिए सही नहीं है।
wikipeda विभिन्न भाषाओं और उनकी छोटी-मोटी परिक्रमा को http://en.wikipedia.org/wiki/Short-circuit_evaluation पर सूचीबद्ध करता है क्योंकि आपके पास कई दृष्टिकोण हैं। और अतिरिक्त समस्याओं की एक जोड़ी मैं यहाँ नहीं जाना है।
विशेष रूप से, फोरट्रान, पास्कल और डेल्फी में संकलक झंडे हैं जो इस व्यवहार को टॉगल करते हैं।
इसलिए: आप पा सकते हैं कि कोड काम करता है जब रिलीज के लिए संकलित किया जाता है, लेकिन डिबग या वैकल्पिक कंपाइलर आदि के लिए नहीं।
कारण 2. भाषा भेद
जैसा कि आप विकिपीडिया से देख सकते हैं, सभी भाषाएं शॉर्ट सर्किटिंग के लिए समान दृष्टिकोण नहीं लेती हैं, तब भी जब वे निर्दिष्ट करते हैं कि बूलियन ऑपरेटरों को इसे कैसे संभालना चाहिए।
विशेष रूप से VB.Net के 'और' ऑपरेटर में शॉर्ट सर्किट नहीं होता है और TSQL में कुछ ख़ासियतें होती हैं।
यह देखते हुए कि एक आधुनिक 'समाधान' में कई भाषाओं को शामिल करने की संभावना है, जैसे कि जावास्क्रिप्ट, रीगेक्स, xpath आदि आपको अपनी कोड कार्यक्षमता स्पष्ट करते समय इसे ध्यान में रखना चाहिए।
कारण 3. किसी भाषा के भीतर का अंतर
उदाहरण के लिए VB की इनलाइन यदि इसके से भिन्न व्यवहार करती है। आधुनिक अनुप्रयोगों में फिर से आपका कोड बीच में आ सकता है, उदाहरण के लिए पीछे कोड और इनलाइन वेबफॉर्म, आपको अर्थ में अंतर के बारे में पता होना चाहिए।
कारण 4. किसी फ़ंक्शन के पैरामीटर की जांच करने वाला नल का आपका विशिष्ट उदाहरण
यह बहुत अच्छा उदाहरण है। इसमें वह कुछ है जो हर कोई करता है, लेकिन वास्तव में बुरा व्यवहार है जब आप इसके बारे में सोचते हैं।
इस तरह के चेक को देखना बहुत ही सामान्य है क्योंकि यह आपके कोड की लाइनों को काफी कम कर देता है। मुझे संदेह है कि कोई भी इसे एक कोड समीक्षा में लाएगा। (और स्पष्ट रूप से टिप्पणियों और रेटिंग से आप देख सकते हैं कि यह लोकप्रिय है!)
हालांकि, यह एक से अधिक कारणों से सर्वोत्तम अभ्यास में विफल रहता है!
कई स्रोतों से यह बहुत स्पष्ट है, सबसे अच्छा अभ्यास यह है कि वैधता के लिए अपने मापदंडों की जांच करने से पहले आप उनका उपयोग करें और यदि वे अमान्य हैं तो अपवाद फेंक दें। आपका कोड स्निपेट आसपास के कोड को प्रदर्शित नहीं करता है, लेकिन आपको शायद कुछ ऐसा करना चाहिए:
if (smartphone == null)
{
//throw an exception
}
// perform functionality
आप सशर्त विवरण के भीतर से एक समारोह बुला रहे हैं । यद्यपि आपके फ़ंक्शन का नाम यह बताता है कि यह केवल एक मूल्य की गणना करता है, यह साइड इफेक्ट्स को छिपा सकता है। जैसे
Smartphone.GetSignal() { this.signal++; return this.signal; }
else if (smartphone.GetSignal() < 1)
{
// Do stuff
}
else if (smartphone.GetSignal() < 2)
{
// Do stuff
}
सर्वोत्तम अभ्यास सुझाएगा:
var s = smartphone.GetSignal();
if(s < 50)
{
//do something
}
यदि आप इन सर्वोत्तम प्रथाओं को अपने कोड में लागू करते हैं, तो आप देख सकते हैं कि छिपे हुए सशर्त के उपयोग के माध्यम से छोटे कोड को प्राप्त करने का आपका अवसर गायब हो जाता है। सबसे अच्छा अभ्यास कुछ करना है , उस मामले को संभालने के लिए जहां स्मार्टफोन शून्य है।
मुझे लगता है कि आप पाएंगे कि अन्य सामान्य उपयोगों के लिए भी यही स्थिति है। आपको याद रखना होगा कि हमारे पास भी है:
इनलाइन सशर्तियां
var s = smartphone!=null ? smartphone.GetSignal() : 0;
और अशक्त सहानुभूति
var s = smartphoneConnectionStatus ?? "No Connection";
जो अधिक स्पष्टता के साथ समान शॉर्ट कोड लंबाई कार्यक्षमता प्रदान करते हैं
मेरे सभी बिंदुओं का समर्थन करने के लिए कई लिंक:
https://stackoverflow.com/questions/1158614/what-is-the-best-practice-in-case-one-argument-is-null
कंस्ट्रक्टर पैरामीटर सत्यापन सी # में - सर्वोत्तम प्रथाओं
क्या किसी को अशक्त होने की जांच करनी चाहिए, यदि वह अशक्त होने की उम्मीद नहीं करता है?
https://msdn.microsoft.com/en-us/library/seyhszts%28v=vs.110%29.aspx
https://stackoverflow.com/questions/1445867/why-would-a-language-not-use-short-circuit-evaluation
http://orcharddojo.net/orchard-resources/Library/DevelopmentGuidelines/BestPractices/CSharp
संकलक झंडे के उदाहरण जो लघु परिचलन को प्रभावित करते हैं:
फोरट्रान: "sce | nosce डिफ़ॉल्ट रूप से, कंपाइलर XL Fortran नियमों का उपयोग करते हुए चयनित तार्किक अभिव्यक्तियों में शॉर्ट सर्किट मूल्यांकन करता है। sce को निर्दिष्ट करने से कंपाइलर गैर-XL Fortran नियमों का उपयोग करने की अनुमति देता है। कंपाइलर शॉर्ट सर्किट मूल्यांकन करेगा यदि वर्तमान नियम इसकी अनुमति देते हैं। । डिफ़ॉल्ट डिफ़ॉल्ट है। "
पास्कल: "बी - एक ध्वज निर्देशन जो शॉर्ट-सर्किट मूल्यांकन को नियंत्रित करता है। शॉर्ट-सर्किट मूल्यांकन के बारे में अधिक जानकारी के लिए डियाडिक ऑपरेटरों के संचालन के मूल्यांकन के आदेश। अधिक जानकारी के लिए कमांड-लाइन कंपाइलर के लिए -sc कंपाइलर विकल्प भी देखें। उपयोगकर्ता के मैनुअल में दस्तावेजित)। "
डेल्फी: "डेल्फी डिफ़ॉल्ट रूप से शॉर्ट सर्किट मूल्यांकन का समर्थन करता है। इसे {$ BOOLEVAL OFF} संकलक निर्देश का उपयोग करके बंद किया जा सकता है।"