2015-09-07 5 views
5

this पृष्ठ पर, मैं निम्नलिखित कोड देखें:अगर ((विशेषताएँ और फ़ाइल एट्रिब्यूट्स। नियुक्त) == FileAttributes.Hidden) {} काम कैसे करता है?

if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) 

लेकिन मुझे समझ नहीं आता क्यों यह तरीका है यह है।

क्यों attributes & FileAttributes.Hidden)? attributes पर एकवचन जांच वास्तव में क्या करती है? क्या यह जांचता है कि यह शून्य नहीं है? मुझे एहसास है मुझे पता है, लेकिन यह अजीब लगता है। यादृच्छिक और अजीब।

+3

इसके बजाय Enum.HasFlag का उपयोग करें (https://msdn.microsoft.com/en-us/library/system.enum.hasflag%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)। – Andrew

+2

[FileAttributes] (https://msdn.microsoft.com/en-us/library/system.io.fileattributes (v = vs.110) .aspx) पृष्ठ को भी पढ़ें। यह कहता है कि इस प्रकार के पास फ्लैग्स एट्रिब्यूट विशेषता है, जिसका अर्थ है कि मूल्य को मूल्यों के सेट के बजाय तार्किक झंडे के संग्रह के रूप में माना जाता है। इसका मतलब है कि आप इसके ध्वज फ़ील्ड को जांचने के लिए तार्किक और ('&') और OR ('|') ऑपरेटैटोट्रोस का उपयोग करते हैं। –

+1

इस उत्तर को एक समान प्रश्न के लिए देखें। बहुत अच्छी तरह से लिखा आईएमओ। http://stackoverflow.com/a/1769814/1260204 – Igor

उत्तर

15

यह आसान बुलियन तर्क है। == ऑपरेटर केवल true देता है यदि दोनों पक्षों के पास एक ही मूल्य है। इसलिए आपको मास्कattributes वैल्यू के साथ मूल्य है जिसके साथ आप तुलना करना चाहते हैं। उन दो उदाहरणों को देखें (मान बने होते हैं):

सच:

0010001 // attributes 
& 0000001 // FileAttributes.Hidden 
    ------- 
= 0000001 // FileAttributes.Hidden 

झूठी:

0011000 // attributes 
& 0000001 // FileAttributes.Hidden 
    ------- 
= 0000000 // FileAttributes.None 
3

& एक बिटवाइज़ और ऑपरेटर है।

यह ऑपरेटर बस थोड़ा सा और बिट्स के 2 सेट करता है।

0 & 0 === 0 
1 & 0 === 0 
0 & 1 === 0 
1 & 1 === 1 

और ऑपरेटर के आगे, एक OR (|) और एक्सओआर (अनन्य OR) (^) ऑपरेटर भी मौजूद है।

+1

^एक एक्सओआर ऑपरेटर है, ~ एक नहीं है। एक्सओआर का मतलब है "1 यदि कोई या तो दोनों बिट्स 1 नहीं हैं", इसका मतलब यह नहीं है कि "1 यदि दोनों बिट्स 0 हैं"। – Kevin

4

attributesFileAttributes प्रकार का है। यह प्रकार एक enum है, एक मान प्रकार। यह FileAttributes? (Nullable<FileAttributes>) नहीं है, इसलिए यह शून्य नहीं हो सकता है।

प्रत्येक enum नामित मूल्यों की एक सूची शामिल है, लेकिन उनमें से प्रत्येक कुछ पूर्णांक (int) मानों के लिए मैपेबल/परिवर्तनीय है। कई स्थानों पर सी # आपको उस रूपांतरण का "शोषण" करने की अनुमति देता है और (कुछ हद तक) enum मानों का इलाज करता है जैसे कि वे स्याही थे, लेकिन फिर भी वे नहीं हैं।

उदाहरण के लिए, & ऑपरेटर जो करता है वह करता है - यह बाइनरी करता है और। इस तरह, यदि enum मान, पूर्णांक में परिवर्तित, प्रासंगिक बिट्स सेट है, तो आपको कुछ nonzero परिणाम मिलेंगे।

कुछ स्थिति मूल्यों में कुछ झंडे/बिट मौजूद हैं या नहीं, यह जांचने के "अच्छे पुराने तरीके" में। आप अक्सर foo & FLAG != 0 जैसे अभिव्यक्ति देख सकते हैं जो जांचता है कि ध्वज सेट है या foo & (FLAG|BLAG) != 0 है जो जांचता है कि इनमें से कोई भी सेट है या नहीं। यह थोड़ा सा दोषपूर्ण/खतरनाक है क्योंकि अगर कोई एक से अधिक बिट रखने के लिए फ्लैग को बदलता है, तो ऐसे अभिव्यक्ति जांचेंगी कि कोई भी सेट सेट है या नहीं, अगर ऐसा पूरा "बहु-बिट ध्वज" सेट नहीं है। यही कारण है कि आप अक्सर foo & FLAG == FLAG देख सकते हैं जो बिटमैस्क लागू करता है और जांच करता है कि परिणाम बिटमास्क है, तो यह जांचता है कि मास्क के सभी बिट सेट हैं या नहीं।

यहां, आपके मामले में यह बस यही है। चूंकि उस अभिव्यक्ति में आप एंडिंग और एक ही मुखौटा के साथ तुलना कर रहे हैं, इसलिए आप प्रभावी रूप से जांच कर रहे हैं कि मुखौटा के सभी बिट सेट हैं या नहीं। लेकिन यह अनिवार्य है क्योंकि FileAttributes को स्पष्ट रूप से [ध्वज] के रूप में चिह्नित किया गया है, Hidden मान में केवल एक बिट है, इसलिए! = 0 पर्याप्त होगा।

हालांकि, इस तरह के मामलों (झंडे, नहीं फैंसी बिटवाइज़ मास्क जाँच) आप Enum.HasFlag विधि का उपयोग करने, ज्यादातर लोगों के लिए, इसका इस्तेमाल करने के बाद से यह इस तरह के मामलों के लिए बनाया गया सलाह देंगे कोशिश कर सकते हैं में;)

यह हालांकि हमेशा सबसे अच्छा चयन नहीं है। कृपया देखें:

..लेकिन मैं अगर है कि प्रदर्शन लागत आप के लिए एक मुद्दा होगा हैरान कर दिया जाएगा। इस बिंदु को अनुकूलित करने की बहुत ही कम आवश्यकता है।

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