2012-10-24 20 views
11

निम्नलिखित कोड पर विचार करें:गलत संकलक चेतावनी तुलना करते समय struct शून्य पर

DateTime t = DateTime.Today; 

bool isGreater = t > null; 

दृश्य स्टूडियो 2010 (सी # 4, .NET 4.0) के साथ, मैं निम्न चेतावनी मिलती है:

चेतावनी CS0458 : अभिव्यक्ति का परिणाम हमेशा 'बूल' प्रकार का 'शून्य' होता है?

यह गलत है;

अब, struct दिनांक समय overloads > (से अधिक) ऑपरेटर: परिणाम हमेशा false (प्रकार bool की) है। कोई भी गैर-शून्य संरचना (जैसे डेटटाइम) संबंधित Nullable<> प्रकार के लिए पूरी तरह से परिवर्तनीय है। उपर्युक्त अभिव्यक्ति

bool isGreater = (DateTime?)t > (DateTime?)null; 

के बराबर बराबर है जो एक ही गलत चेतावनी उत्पन्न करती है। यहां > ऑपरेटर ऑपरेटर उठाया गया है। यह झूठी लौटकर काम करता है अगर उसके दो ऑपरेटरों में से HasValuefalse है। अन्यथा, उठाया ऑपरेटर अंतर्निहित संरचना में दो ऑपरेटरों को खोलने के लिए आगे बढ़ेगा, और फिर उस संरचना द्वारा परिभाषित > के ओवरलोड को कॉल करें (लेकिन इस मामले में यह आवश्यक नहीं है जहां एक ऑपरेंड HasValue नहीं है)।

क्या आप इस बग को पुन: पेश कर सकते हैं, और क्या यह बग अच्छी तरह से ज्ञात है? क्या मैंने कुछ गलत समझा है?

यह सभी संरचना प्रकारों के लिए समान है (int जैसे सरल प्रकार नहीं, और enum प्रकार नहीं) जो ऑपरेटर को प्रश्न में अधिभारित करते हैं।

(अब मैं अगर हम > के बजाय == उपयोग करते हैं, सब कुछ पूरी तरह से समान होने के लिए (क्योंकि दिनांक समय भी == ऑपरेटर) overloads। लेकिन यह समान नहीं है चाहिए। अगर मैं कहता हूँ

DateTime t = DateTime.Today; 

bool isEqual = t == null; 

मिल कोई चेतावनी ☹ कभी-कभी आप लोगों को गलती से एक चर या पैरामीटर की जांच करते हैं, यह महसूस नहीं करते कि उनके चर का प्रकार एक संरचना है (जो == ओवरलोड करता है और यह int जैसे साधारण प्रकार का नहीं है)। अगर उन्हें चेतावनी मिलती तो बेहतर होगा ।)


अद्यतन: विजुअल स्टूडियो 2015 के सी # 6.0 संकलक (Roslyn के आधार पर) के साथ, isGreater साथ गलत संदेश के ऊपर एक सही और उपयोगी चेतावनी संदेश के साथ एक CS0464 में बदल जाता है। इसके अलावा, ऊपर isEqual के साथ चेतावनी की कमी VS2015 के कंपाइलर में तय की गई है, लेकिन केवल तभी जब आप /features:strict के साथ संकलित हों।

+0

'[कुछ भी]> नल 'से शुरू करने के लिए कोई समझ नहीं आता है (मेरे लिए, कम से कम)। दिलचस्प सवाल फिर भी, मुझे लगता है कि इसे 'झूठी' के रूप में हमेशा 'झूठी' के रूप में समाप्त होने के बारे में चेतावनी दी जानी चाहिए। – Alex

+1

उपयोगी हो सकता है: http://blogs.msdn.com/b/abhinaba/archive/2005/12/11/501544.aspx और http://blogs.msdn.com/b/abhinaba/archive/2005/12 /14/503533.aspx – Habib

+0

दिलचस्प बात यह है कि 'dateTime.CompareTo (ऑब्जेक्ट) '_pepecifically_'' n' 'की तुलना करते समय' null' 'की तुलना करता है, जो भी ऑब्जेक्ट प्रकार गुजरता है। – Rawling

उत्तर

5

आप सही हैं: यह विजुअल स्टूडियो में एक बग है। सी # 4.0 मानक (§ 7.3.7 लिफ़्टेड ऑपरेटरों) इस कहना है:

संबंधपरक ऑपरेटर

< > <= >= 

[...] उठाया ऑपरेटर मूल्य false पैदा करता है अगर एक या दोनों ऑपरेंड के लिए शून्य हैं ...

और वास्तव में, monodevelop में, आपको निम्न चेतावनी बजाय:

null साथ प्रकार System.DateTime की तुलना का परिणाम हमेशा false है।

+0

लेकिन, इस' > मामला, परिणाम झूठा है, शून्य नहीं। परिणाम का प्रकार 'बूल' है, न कि 'बूल?'। – Rawling

+0

@ राउलिंग क्या यह है? यह गलत लगता है, ऑपरेटर उठाए जाने के बाद से यह निश्चित रूप से 'बूल' होना चाहिए। –

+0

विजुअल स्टूडियो ऐसा सोचता प्रतीत होता है, लेकिन 'डेटटाइम। आज> नल' मुझे 'bool' प्रकार का 'झूठा' देता है, और पूछताछकर्ता स्पष्ट रूप से मिलता है। मैं सहमत हूं कि यह अजीब है। – Rawling

1
DateTime t = DateTime.Today; 

bool isGreater = (DateTime?)t > (DateTime?)null; 

इस परिदृश्य में t > null के बारे में चेतावनी क्या है। यह कभी सच नहीं होगा। क्योंकि इसका मूल्यांकन नहीं किया जा सकता है।

इस परिदृश्य में:

bool isGreater = (DateTime?)t > (DateTime?)null; 

हम (DateTime?)t > (DateTime?)null मूल्यांकन कर रहे हैं;

या अनिवार्य रूप से सबसे अच्छे मामले परिदृश्य में t > null; पहले की तरह। डेटटाइम.अब अपरिभाषित से अधिक कभी नहीं हो सकता है, इसलिए चेतावनी।

+0

मैं सहमत हूं कि यह एक चेतावनी के साथ प्रासंगिक है, लेकिन क्या आपने चेतावनी ** संदेश ** पढ़ा है? यह चेतावनी का पाठ है जो परेशान रूप से गलत है, तथ्य यह नहीं कि एक चेतावनी उत्सर्जित होती है। (हो सकता है कि कुछ समय पर निरर्थक प्रकार के विकास के दौरान उन्होंने तुलना के उठाए गए ऑपरेटरों ('>', '==', और इसी तरह) व्यवहार करने की योजना बनाई, लेकिन फिर उनके दिमाग बदल गए?) –

9

रोज़लिन में उठाए गए ऑपरेटर व्यवहार को लागू करते समय मैंने स्वतंत्र रूप से इस त्रुटि की खोज की, और मैंने इसे छोड़ने से पहले रोज़लिन में इसे ठीक किया।

क्षमा करें कि जब आपने इसे अक्टूबर में पोस्ट किया था तो मुझे यह नहीं देखा था। कनेक्ट करने के लिए इसे सबमिट करने के लिए धन्यवाद! और त्रुटि के लिए कई क्षमा चाहते हैं; यह ऑपरेटर अर्थपूर्ण विश्लेषण में एक लंबे समय से त्रुटि है।

संयोग से, मैं चर्चा करेंगे कि कैसे रोसलिन http://ericlippert.com बाद में इस महीने (दिसंबर 2012) पर भाव उठा लिया अनुकूलित करता है, इसलिए यदि इस विषय में रुचि है, चेक करें:

http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/

+3

स्टैक ओवरफ़्लो पर प्रत्येक थ्रेड को देखने के लिए क्षमा मांगने की आवश्यकता नहीं है। मुझे उम्मीद है कि मुझे उठाए गए ऑपरेटरों पर आपकी आने वाली पोस्ट की जांच करना याद है। –

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