2016-05-17 8 views
22

मैंने अभी वीएस 2010 से 2015 तक अपग्रेड किया है। मुझे नया null-conditional operator पसंद है जिसे नल-प्रोपेगेशन भी कहा जाता है। इस उदाहरण के लिए, अपने कोड को आसान बनाने के लिए सक्षम बनाता है:नल-सशर्त ऑपरेटर बूल को न करने का मूल्यांकन करता है? जैसा कि

string firstCustomerName = customers?[0].Name; // null if customers or the first customer is null 

एक और एक:

int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null 

जो एक Nullable<int> भी Enumerable.Count अगर रिटर्न एक int एक वैध गिनती और से पहले किसी भी nulls के बीच अंतर करने देता है। यह काफी सहज और बहुत उपयोगी है।

लेकिन क्यों यह संकलन और काम के रूप में उम्मीद (यह रिटर्न false) करता है:

string text = null; 
bool contains = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase) >= 0; 

यह या तो लौटना चाहिए bool? संकलन (नहीं जो यह करता है) या नहीं।

+5

अरे, मुझे लगता है कि मुझे यह मिल गया है, आप कर सकते हैं इसे फिर से लिखें: 'int? indexof = text ?IndexOf ("Foo", StringComparison.CurrentCultureIgnoreCase); बूल में = indexof> = 0; ' –

+4

मैं'?> = 'ऑपरेटर के लिए वोट दूंगा।:) –

+0

@DStanley: तो प्राथमिक में से अन्य [ऑपरेटर श्रेणियां] (https://msdn.microsoft.com/en-us/library/aa691323 (v = vs.71) .aspx) शामिल है? अच्छा से ज्यादा नुकसान होगा। –

उत्तर

28

क्या आप वास्तव में है

string text = null; 
int? index = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase); 
bool contains = index >= 0; 

और int? >= int पूरी तरह से कानूनी है।

कारण यह विभाजित किया गया था वहाँ the documentation for the operator राज्यों "शून्य है, तो चेन के निष्पादन के बाकी बंद हो जाता है सशर्त सदस्य का उपयोग और सूचकांक आपरेशन की एक श्रृंखला में एक आपरेशन रिटर्न। अन्य संचालन कम पूर्वता के साथ अभिव्यक्ति में जारी है। " इसका मतलब है कि .? केवल "एक मूल्य बनाता है" इससे पहले ही वही प्राथमिकता या उच्चतर चीज़ों का मूल्यांकन करेगा।

यदि आप the order of operator precedence देखते हैं तो आप देखेंगे कि "रिलेशनल और टाइप-टेस्टिंग ऑपरेटर" सूची में बहुत कम हैं, इसलिए >= लागू होने से पहले मूल्य बनाया जाएगा।


अद्यतन: क्योंकि यह टिप्पणी में लाया गया था, यहां >= और अन्य ऑपरेटरों कैसे व्यवहार जब एक नल मूल्य के साथ काम पर सी # 5 कल्पना खंड है। मैं सी # के लिए एक दस्तावेज 6.

7.3.7 लिफ़्टेड ऑपरेटरों

लिफ़्टेड ऑपरेटरों नहीं पा सके परमिट पूर्वनिर्धारित और उपयोगकर्ता परिभाषित ऑपरेटरों कि गैर-व्यर्थ मूल्य प्रकार पर काम भी नल के साथ प्रयोग की जाने वाली उन प्रकार के रूपों। उठा लिया ऑपरेटरों, पूर्वनिर्धारित और उपयोगकर्ता परिभाषित ऑपरेटरों कि कुछ आवश्यकताओं को पूरा से निर्माण कर रहे हैं निम्नलिखित में वर्णित हैं:

  • एकल ऑपरेटरों
    + ++ - -- ! ~

    एक ऑपरेटर के एक उठाया प्रपत्र अगर मौजूद है के लिए ऑपरेंड और परिणाम प्रकार दोनों गैर-शून्य मूल्य प्रकार हैं। उठाया गया फॉर्म एक एकल जोड़कर बनाया गया है? ऑपरेंड के लिए संशोधक और परिणाम प्रकार। ऑपरेटर शून्य है, तो उठाया ऑपरेटर शून्य मान देता है।अन्यथा, उठाया ऑपरेटर ऑपरेंड को अनचाहे करता है, अंतर्निहित ऑपरेटर लागू करता है, और परिणाम को लपेटता है।

  • द्विआधारी ऑपरेटरों
    लिए + - */% & |^<< >>

    एक ऑपरेटर के एक उठाया रूप से मौजूद है, तो संकार्य और परिणाम प्रकार सभी गैर-व्यर्थ मूल्य प्रकार हैं। उठाया गया फॉर्म द्वारा एकल जोड़ा गया है? प्रत्येक ऑपरेंड और परिणाम प्रकार के लिए संशोधक। उठाए गए ऑपरेटर एक शून्य मान उत्पन्न करते हैं यदि एक या दोनों ऑपरेशंस शून्य हैं ( अपवाद & और बूल के ऑपरेटर हैं? प्रकार, जैसा कि को §7.11.3 में वर्णित किया गया है)। अन्यथा, उठाए गए ऑपरेटर ऑपरेटरों को अनचाहे करते हैं, अंतर्निहित ऑपरेटर को लागू करता है, और परिणाम को लपेटता है।

  • समानता ऑपरेटरों
    == !=

    एक ऑपरेटर के एक उठाया रूप से मौजूद है, तो संकार्य प्रकार दोनों गैर-व्यर्थ मूल्य प्रकार के होते हैं और यदि परिणाम प्रकार bool है

    । उठाए गए फ़ॉर्म को एकल जोड़कर बनाया गया है? प्रत्येक ऑपरेंड प्रकार के लिए संशोधक। उठाया ऑपरेटर दो शून्य मानों को बराबर मानता है, और एक शून्य किसी भी गैर-शून्य मान के बराबर मूल्य मानता है। यदि दोनों ऑपरेंड गैर-शून्य हैं, उठाए गए ऑपरेटर ऑपरेंड को अनचाहे करते हैं और बूल परिणाम उत्पन्न करने के लिए अंतर्निहित ऑपरेटर लागू करते हैं।

  • संबंधपरक ऑपरेटर
    < > <= >=

    एक ऑपरेटर के एक उठाया रूप से मौजूद है, तो संकार्य प्रकार दोनों गैर-व्यर्थ मूल्य प्रकार के होते हैं और परिणाम प्रकार bool है अगर के लिए

    । उठाए गए फ़ॉर्म को एकल जोड़कर बनाया गया है? प्रत्येक ऑपरेंड प्रकार के लिए संशोधक। उठाए गए ऑपरेटर मूल्य को गलत बनाते हैं यदि एक या दोनों ऑपरेंड शून्य हैं। अन्यथा, उठाए गए ऑपरेटर ऑपरेटरों को खोलता है और बूल परिणाम उत्पन्न करने के लिए अंतर्निहित ऑपरेटर को लागू करता है।

+0

सी # में अधिक ज्ञान के बिना हम में से उन लोगों के लिए, ऑपरेटर '> =' का व्यवहार क्या होता है जब 'Nullable' वास्तव में शून्य है? – njzk2

+0

@ njzk2 सरल शब्दों में, यदि '> =' के दोनों ओर या दोनों तरफ शून्य हैं तो यह हमेशा झूठी वापसी करेगा। पूर्ण spec के लिए मेरा अद्यतन देखें। –

+0

धन्यवाद @ScottChamberlain – njzk2

3

आप इस कोड का उपयोग करते हैं, और x पर होवर करें, आप देखते हैं कि x एक int? है:

var x = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase); 
bool contains = x >= 0; 

तो टाइपिंग अभी भी सही है।

फिर x >= 0 देखें: यह int? >= int है। स्पष्ट रूप से शून्य और गैर-नालीदार structs के बीच एक ऑपरेटर है। यही कारण है कि यह काम करता है।

यदि आप आईएल देखते हैं, तो आप देखेंगे कि यह वास्तव में HasValue और GetValueOrDefault() पर कॉल करेगा। मुझे लगता है कि यह एक ऑपरेटर है, लेकिन मुझे संदर्भ स्रोत में नहीं मिला, इसलिए यह सीएलआर या कंपाइलर में होना चाहिए:

instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault() 

... 
instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue() 
+1

सच है, लेकिन यह हो सकता है कि शून्य-सशर्त ऑपरेटर में '> =' ऑपरेटर शामिल होगा जो 'बूल' वापस करेगा? लेकिन मुझे लगता है कि यह [_ "अभिव्यक्ति में निचली प्राथमिकता वाले अन्य परिचालनों के साथ है" _] (https://msdn.microsoft.com/en-us/library/dn986595.aspx) के साथ है। –

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