2008-12-11 9 views
15

एक उत्तर और बाद में debate in the comments किसी अन्य धागे में मुझे यह पूछने के लिए प्रेरित किया:सी # शॉर्ट सर्किट मूल्यांकन से संबंधित सबसे अच्छा अभ्यास क्या है?

सी # || और & & लॉजिकल ऑपरेटरों के संक्षिप्त सर्किट संस्करण हैं। और & क्रमशः।

उदाहरण उपयोग:

if (String.IsNullOrEmpty(text1) | String.IsNullOrEmpty(text2) | String.IsNullOrEmpty(text3)) 
{ 
    //... 
} 

बनाम:

if (String.IsNullOrEmpty(text1) || String.IsNullOrEmpty(text2) || String.IsNullOrEmpty(text3)) 
{ 
    //... 
} 

अभ्यास है जो बेहतर इस्तेमाल करते हैं और यही कारण है कि करने के लिए कोडिंग के संदर्भ में?

नोट: मुझे एहसास है कि यह प्रश्न this question जैसा है लेकिन मेरा मानना ​​है कि यह एक भाषा विशिष्ट चर्चा की गारंटी देता है।

उत्तर

44

कोडिंग अभ्यास के संदर्भ में जो उपयोग करना बेहतर है और क्यों?

सरल उत्तर: हमेशा संक्षिप्त सर्किट संस्करणों का उपयोग करें। ऐसा करने का कोई कारण नहीं है। इसके अतिरिक्त, आप अपना कोड स्पष्ट करते हैं क्योंकि आप अपना इरादा व्यक्त करते हैं: तार्किक मूल्यांकन। बिटवाई (लॉजिकल) ऑपरेशंस का उपयोग करने का तात्पर्य यह है कि आप केवल यही चाहते हैं: बिट ऑपरेशंस, तार्किक मूल्यांकन नहीं (भले ही एमएसडीएन उन्हें "तार्किक ऑपरेटरों" भी कहता है, जब बूलियन मानों पर लागू होता है)।

इसके अतिरिक्त, के बाद से शॉर्ट-सर्किट केवल मूल्यांकन करता है क्या का मूल्यांकन की जरूरत है, यह अक्सर तेजी से है, और यह इस तरह के कोड, अर्थात् लिखने के रूप में

bool nullorempty = str == null || str.Length == 0; 

(ध्यान दें कि इस विशेष समस्या एक बेहतर कार्य पहले से मौजूद है हल करने के लिए अनुमति देता है string.IsNullOrEmpty जिसे आपने अपने प्रश्न में भी प्रयोग किया था।) यह कोड बिटवाई लॉजिकल ऑपरेशंस के साथ संभव नहीं होगा क्योंकि strnull थे, दूसरी अभिव्यक्ति का मूल्यांकन किया जाएगा, जिसके परिणामस्वरूप NullReferenceException होगा।

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

इसके बजाय, आप पक्ष पर भरोसा करने के लिए है, प्रभाव, उन्हें स्पष्ट करना:

bool hasBuzzed = checkMakeBuzz(); 
bool isFrobbed = checkMakeFrob(); 
bool result = hasBuzzed || isFrobbed; 

दी, एक के बजाय तीन लाइनों। लेकिन परिणामस्वरूप एक बहुत स्पष्ट कोड।

+1

यह एक अच्छा जवाब आइए, लेकिन आप "तार्किक" और "तार्किक" के लिए "सशर्त" से "बिटवाइज़" ऑपरेटरों को बदल सकते हैं? यह शब्दावली एमएसडीएन उपयोग करता है। तकनीकी रूप से दोनों "तार्किक" हैं लेकिन दोगुनी संस्करण भी शॉर्ट-सर्किट – Jimmy

+0

"सशर्त-और ऑपरेटर (&&) तार्किक-और इसके बूल ऑपरेंड का प्रदर्शन करता है, लेकिन यदि आवश्यक हो तो केवल दूसरे ऑपरेंड का मूल्यांकन करता है।" "http://msdn.microsoft.com/en-us/library/2a723cdk(VS.71).aspx" – Jimmy

+4

बिल्कुल सही उत्तर। साइड इफेक्ट चर्चा के लिए +1 - रखरखाव के लिए सहमत, हमेशा स्पष्ट हो। 3 एलओएस बनाम रखरखाव दुःस्वप्न, 3 एलओसी हाथ से नीचे जीतता है। –

1

उपयोग && और || जब आप केवल परिणाम के बारे में परवाह है और जितनी जल्दी हो सके कि परिणाम जानना चाहते हैं और अपने भाव से कोई साइड इफेक्ट भी है कि होने चाहिए अगर बूलियन शर्त पूरी नहीं है। यही कहना है, हमेशा बहुत ज्यादा।

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

उदाहरण के लिए, यह शायद असाधारण मूर्खतापूर्ण होगा:

if (false & somethingThatUpdatesTheDatabase()) { /* ... */ } 
7

मैं रिवर्स में इस सवाल का जवाब करने जा रहा हूँ: जब केवल बार मैं तर्क ऑपरेटरों का उपयोग है?

मैं कभी कभी तार्किक तुलना का उपयोग जब मैं (कम लागत) सशर्त, कि सभी पूरा किया जाना चाहिए की एक श्रृंखला होगा। उदाहरण के लिए:

return (isEightCharacters(password) && 
     containsNumberic(password) && 
     containsBothUppercaseAndLowercase(password)); 

नकारात्मक पक्ष यह है कि यह थोड़ा अधिक गूढ़ है:

bool isPasswordValid = true; 

isPasswordValid &= isEightCharacters(password); 
isPasswordValid &= containsNumeric(password); 
isPasswordValid &= containsBothUppercaseAndLowercase(password); 

return isPasswordValid; 

मेरी राय में, इसके बाद के संस्करण की तुलना में अधिक पठनीय है।

+0

आह, बिटवाई असाइनमेंट ऑपरेटरों का दिलचस्प उपयोग। धन्यवाद! – mdwhatcott

+1

आपके उदाहरण में कड़ाई से, यदि पासवर्ड 7 वर्ण है, तो यह मान्य नहीं है। तो क्या इसमें संख्यात्मक और/या ऊपरी/लोअरकेस अप्रासंगिक है और कुछ भी नहीं बदलता है। शॉर्ट सर्किटिंग वास्तव में लागू किया जाना चाहिए।यदि एक एकल रिटर्न स्टेटमेंट की पठनीयता एक मुद्दा है, तो आप कोड को तीन पंक्तियों में बदल सकते हैं जो कहते हैं: 'अगर (! आवश्यकता जांच (इनपुट)) झूठी वापसी;' तो आखिरी पंक्ति को सिर्फ 'सच वापसी' कहना चाहिए; हालांकि, अगर आप प्रत्येक req चाहता था। एक विशिष्ट संदेश लौटने के लिए चेक किया गया है, फिर संदेशों को गठबंधन करें, फिर यह उदाहरण अब इस प्रश्न पर लागू नहीं होता है और हमारे पास अधिक अपरिहार्यता है। – Suamere

+0

मैं कभी-कभी लूप के अंदर इस तरह से bitwise असाइनमेंट ऑपरेटर का उपयोग करता हूं, उदाहरण के लिए। 'पूर्णांक राशि = 0;' ' bool anyOdd = false;' ' foreach (GetNumbers में पूर्णांक संख्या())' ' {' ​​' योग + = संख्या;' ' anyOdd | = संख्या% 2 == 1; ' '} ' लेकिन इस जवाब में मैं @ सुमेरे से सहमत हूं कि शॉर्ट सर्किटिंग क्लीनर है। – hypehuman

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