नल दिए जाने पर ऑपरेटर वापस क्यों झूठ बोलता है?


135

यह मुझे लगता है कि isऑपरेटर थोड़ा असंगत है।

bool Test()
{
    // Returns false, but should return true.
    return null is string;
}

एक को उम्मीद है कि nullमूल्य किसी भी संदर्भ (या अशक्त) प्रकार का है। और वास्तव में, सी # भाषा विनिर्देश ऐसा कुछ कहता है जो इस परिकल्पना का समर्थन करता है, उदाहरण के लिए (6.1.6 निहित संदर्भ रूपांतरण):

अंतर्निहित संदर्भ रूपांतरण हैं:
...
• अशक्त शाब्दिक से किसी भी संदर्भ-प्रकार के लिए।

के वर्णन (7.10.10 ऑपरेटर है) isकह रही है कि अभिव्यक्ति द्वारा ऑपरेटर शुरू होता है (E is T)सच में परिणाम होगा जब से एक संदर्भ रूपांतरण Eकरने के लिए Tमौजूद है, लेकिन फिर लेखकों को स्पष्ट रूप से मामला को छोड़कर जब से चले जाते Eहै nullशाब्दिक या एक है nullमूल्य ।

वे ऐसा क्यों करते हैं? मेरे लिए यह उल्टा लगता है।


क्यों वे स्पष्ट रूप से शून्य से बाहर रखा गया है programmers.stackoverflow.com के लिए एक सवाल पर सबसे अच्छा है
दुखी परिवर्तनीय

2
मैं अपने करीबी वोट को नहीं बचा सकता
मॉर्गन-ग्राहम

java में null typeof Objectभी झूठा लौटता है
शाफ़्ट फ्रीक

माना कि null is stringथे true, और यह निहित है कि nullएक है string। इसके अलावा मान लेते हैं कि null is Nullable<int>है true, जिसका अर्थ है कि nullएक है Nullable<int>। अब, इस प्रश्न का उत्तर दें: किस प्रकार का है null?
बजे एक CVn

1
@ मिकेल कीजर्लिंग: नॉन सीक्वेटुर। उल्लिखित तथ्यों से (null is a string, null is a Nullable <int>) यह इस बात का पालन नहीं करता है कि मुझे उस प्रश्न का उत्तर देने में सक्षम होना चाहिए।
गेब ऑक्ट

जवाबों:


195

यह प्रश्न ३० मई २०१३ को मेरे ब्लॉग का विषय था । महान प्रश्न के लिए धन्यवाद!


आप एक खाली ड्राइववे पर घूर रहे हैं।

कोई आपसे पूछता है "क्या आपका ड्राइववे होंडा सिविक पकड़ सकता है?"

हाँ। हाँ यह कर सकते हैं।

कोई आपको दूसरे ड्राइववे पर बताता है। यह भी खाली है। वे पूछते हैं "क्या मेरे ड्राइववे की वर्तमान सामग्री आपके ड्राइववे में फिट हो सकती है?"

हाँ, ज़ाहिर है। दोनों ड्राइववे खाली हैं! तो स्पष्ट रूप से एक की सामग्री दूसरे में फिट हो सकती है, क्योंकि पहली जगह में कोई भी सामग्री नहीं है।

कोई आपसे पूछता है "क्या आपके ड्राइववे में होंडा सिविक है?"

नहीं, यह नहीं है।

आप सोच रहे हैं कि isऑपरेटर दूसरे प्रश्न का उत्तर देता है: इस मूल्य को देखते हुए, क्या यह उस प्रकार के चर में फिट होता है? क्या एक शून्य संदर्भ इस प्रकार के एक चर में फिट बैठता है? हाँ यह करता है।

यह सवाल नहीं है कि isऑपरेटर जवाब देता है। सवाल यह है कि isऑपरेटर जवाब तीसरा सवाल है। y is Xनहीं पूछता है " है yप्रकार का एक चर के एक कानूनी मूल्य X? " यह पूछते हैं, " है yप्रकार का ऑब्जेक्ट के लिए एक वैध संदर्भ X? " जब से एक अशक्त संदर्भ के लिए एक वैध संदर्भ नहीं है किसी भी का उद्देश्य किसी भी प्रकार, इस सवाल का जवाब "नहीं है "। वह मार्ग खाली है; इसमें होंडा सिविक शामिल नहीं है।

इसे देखने का एक और तरीका यह है कि y is Xप्रश्न का उत्तर "यदि मैंने कहा y as X, तो क्या मुझे एक अशक्त परिणाम मिलेगा? यदि y शून्य है, तो स्पष्ट रूप से उत्तर नहीं है!"


अपने प्रश्न पर थोड़ा गहरा देखने के लिए:

एक को उम्मीद है कि अशक्त मूल्य किसी भी संदर्भ (या अशक्त) प्रकार का है

एक का अर्थ यह माना जाएगा कि एक प्रकार मानों का एक सेट है , और टाइप x के एक चर के साथ एक मूल्य y की असाइनमेंट संगतता कुछ भी नहीं है और न ही जाँच से कम है कि क्या y सेट x का सदस्य है

यद्यपि यह प्रकारों को देखने का एक बहुत ही सामान्य तरीका है, लेकिन यह प्रकारों को देखने का एकमात्र तरीका नहीं है , और यह वह तरीका नहीं है जो C # प्रकारों को देखता है। अशक्त संदर्भ C # में किसी प्रकार के सदस्य नहीं हैं; काम अनुकूलता है नहीं केवल एक सेट की जाँच देखने के लिए अगर उसमें कोई मान। सिर्फ इसलिए कि एक शून्य संदर्भ असाइनमेंट प्रकार के एक चर के साथ संगत असाइनमेंट है एक्स का मतलब यह नहीं है कि शून्य प्रकार एक्स का सदस्य है। "असाइनमेंट" संबंध के साथ संगत है और "प्रकार का सदस्य है" संबंध स्पष्ट रूप से बहुत सारे हैं ओवरलैप, लेकिन वे सीएलआर में समान नहीं हैं।

यदि आप सिद्धांत के बारे में रुचि रखते हैं, तो इस विषय पर मेरे हाल के लेख देखें:

इस चीज़ को आप "प्रकार" कहते हैं? भाग एक

इस चीज़ को आप "प्रकार" कहते हैं? भाग दो


@ गीब: मदद करने के लिए खुशी है। यह लेख आपके लिए भी रुचिकर हो सकता है: blogs.msdn.com/b/ericlippert/archive/2010/09/16/…
एरिक

एरिक ने इसे एक ब्लॉग पोस्ट में बदल दिया: ericlippert.com/2013/05/30/what-the-meaning-of-is-is
केविन

y is Xयह नहीं पूछता "क्या प्रकार का yएक वैधानिक मूल्य है X?" यह पूछता है "क्या yकिसी प्रकार की वस्तु का वैध संदर्भ है X?" यह पूरी बात थी! धन्यवाद!
जलाल

लेकिन अगर मैं पूछता हूं y is int?, तो मैं पूछूंगा कि "क्या आपके ड्राइववे में होंडा सिविक है या कुछ भी नहीं है?"। जब आपका ड्राइववे खाली हो तब भी उत्तर क्यों नहीं है? यदि आप हुड के नीचे देखते हैं तो यह केवल खराब हो जाता है, जैसा कि यह सवाल बन जाता है कि "क्या आपके ड्राइववे में होंडा सिविक है या एक संकेत है जो कहता है कि 'नो होंडा सिविक'?"। यहां तक ​​कि अगर आपके ड्राइववे में साइन कहा गया है, तो भी जवाब नहीं है।
फैक्स

1
@Gerard: जब मैं लंबे, क्रियात्मक, गपशप उत्तर देता हूं, तो लोग मुझे बताते हैं कि उन्हें छोटा होना चाहिए, और जब मैं संक्षिप्त जवाब देता हूं, तो लैकोनिक जवाब देते हैं कि लोग मुझे बताते हैं कि उन्हें लंबा होना चाहिए। मेरा निष्कर्ष है: लोग शिकायत करना पसंद करते हैं। चूँकि आपके मन में इस बारे में भावनाएँ हैं कि इस आठ साल पुराने प्रश्न का अच्छा उत्तर क्या है, मेरा सुझाव यह है कि आप हमें यह बताएं कि इसका उत्तर देने से क्या अच्छा उत्तर मिलता है, ताकि हम सीख सकें।
एरिक लिपर्ट

24

मुझे लगता है कि null is stringझूठे लौटना बहुत सहज है। नल का मतलब कुछ भी नहीं है, और यह निश्चित रूप से एक स्ट्रिंग नहीं है। अतः इसे असत्य लौटना चाहिए। हालांकि यह एक विकल्प है जिसे भाषा डिजाइनर बना रहे हैं, यह एक बहुत ही सहज ज्ञान युक्त है जब आप वास्तविक दुनिया को अशक्त मानते हैं।


2
+1 क्योंकि सवाल वास्तव में इस बारे में है कि क्या यह सहज है और उस युक्ति पर सवाल नहीं उठा रहा है, जिसे ओपी पहले से जानता है। यदि आप इसे अंग्रेजी वाक्य के रूप में पूछते हैं " nullएक स्ट्रिंग है" उत्तर है नहीं, यह नहीं है, जो "से अलग nullहै string"
Davy8

null is stringबहुत सहज है, (string)null is stringअगर आपको C # में एक शून्य संदर्भ कैसे काम करता है, तो आप वास्तव में परिचित नहीं हैं।
10

24

nullशाब्दिक को सौंपा जा सकता है किसी भी संदर्भ प्रकार। यह अपने आप में एक प्रकार नहीं है। यह एक विशेष शाब्दिक है जो एक शून्य संदर्भ का प्रतिनिधित्व करता है।

उस isस्थिति में trueजब कोई पास nullहो जाएगा, तो आप nullशाब्दिक के साथ क्या कर पाएंगे ? कुछ भी नहीं - यह हैnulltrueभ्रमित करने वाले मामलों को छोड़कर लौटने का क्या मतलब होगा ?


चाहे - कितना सहज हो, इस संदर्भ में अंग्रेजी में कोड पढ़ें और मुझे बताएं:

null is string;

जब मैं देखता हूं, तो यह सवाल पूछ रहा है is "nothing" a string?। मेरा अंतर्ज्ञान मुझे बताता है कि नहीं, यह नहीं है - यह है nothing


यह ठीक है, लेकिन फिर यह भी एक स्ट्रिंग है, है ना? लेकिन (null is string)फिर भड़कता क्यों है ?
गब्ब

मैंने इसे दूसरे तरीके से गोल किया होगा। कोई भी संदर्भ प्रकार अशक्त हो सकता है। null सिर्फ null है।
मार्क एच।

@Oled तो शून्य मान का मान मान है, कहते हैं, ऑब्जेक्ट प्रकार? मैं इसे इस प्रकार के एक चर के लिए असाइन कर सकता हूं, है ना? तो उत्तर हां लगता है, मान पूरी तरह से मान्य है, और मेरा अनुमान है कि (null is object)अभिव्यक्ति को बिल्कुल जांचना चाहिए।
गेब

@ गीब: यह मत भूलो कि ValueTypes भी ऑब्जेक्ट हैं, लेकिन संदर्भ प्रकार नहीं।
मार्क एच।

1
@Oded: "यह भ्रमित करने वाले मामलों को छोड़कर सही मायने में लौटने का क्या होगा?" दरअसल, यह भाषा को अधिक तार्किक बनाता है। इन दो बिंदुओं पर विचार करें: (1) isऑपरेटर जाँचता है कि क्या एक संदर्भ (हमें यहां अन्य प्रकार के रूपांतरण की आवश्यकता नहीं है) रूपांतरण मौजूद है; (2) nullकिसी भी संदर्भ प्रकार में परिवर्तित किया जा सकता है। इसलिए (null is T), जहां T एक संदर्भ प्रकार है, उसे सही लौटना चाहिए। लेकिन नहीं, यहाँ हमारे पास वह स्पष्ट अपवाद है, जो मुझे भ्रमित करने वाला लगता है।
गिबेब

12

http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.71%29.aspx

निम्न स्थितियों के दोनों पूरा होने पर अभिव्यक्ति सत्य का मूल्यांकन करती है:

  • अभिव्यक्ति शून्य नहीं है।
  • अभिव्यक्ति टाइप करने के लिए डाली जा सकती है। यही है, फ़ॉर्म का एक कास्ट एक्सप्रेशन (प्रकार (एक्सप्रेशन) बिना किसी अपवाद के पूरा हो जाएगा)। अधिक जानकारी के लिए, 7.6.6 कास्ट एक्सप्रेशन देखें।

1
वैसे भी प्रलेखन में केवल यह कहा गया है कि अभिव्यक्ति शून्य नहीं हो सकती है (जो हम पहले से जानते हैं), लेकिन यह नहीं बताता कि क्यों
यूज़र

आप इसे किसी अन्य तरीके से क्यों चाहेंगे?
सहनीय चर

1
@username: यह उत्तर यांत्रिक तरीके से काम करने के तरीके को बताता है, और एक संदर्भ का हवाला देता है, जो आपको काम करने के लिए एक मॉडल देता है। आप यहां ब्रह्मांड का अर्थ पूछ रहे हैं। मुझे लगता है कि आप भाग्यशाली हैं कि हमारे भगवान एसओ;)
मेरलिन मॉर्गन-ग्राहम

10

एक व्यावहारिक बात के रूप में, "null is T == false" होना मुझे अतिरिक्त कोड लिखने से बचाता है:

कहने के बजाय

if (X != null && X is Foo) {}

मैं बस कह सकता हूं

if (X is Foo) {}

और इसके साथ किया जाए।


8

nullमूल्य

मैंने इसे आपके प्रश्न से उद्धृत किया है क्योंकि यह इस मामले के दिल में पहुंचता है। एक मूल्य null नहीं है - यह एक मूल्य का अभाव है। isमेरे लिए इस सवाल का जवाब देना उद्देश्य है :

अगर मैं कास्ट Eकरता हूं T, तो क्या मुझे सफलता मिलेगी T?

अब, आप जबकि कर सकते हैं डाली nullको T त्रुटि के बिना , करने के बाद तो आप नहीं है "एक है T" - आप अभी भी मिल गया है कुछ भी नहीं है। तो यह मामला नहीं है कि null"ए" है T, इसलिए isझूठे रिटर्न।


3

जावा में एक ऑपरेटर होता है जो बिल्कुल वैसा ही काम करता है, लेकिन इसका बहुत लंबा नाम है instanceof:। यह बहुत सहज है कि null instanceof Stringझूठे लौटते हैं, क्योंकि अशक्त किसी भी चीज का उदाहरण नहीं है, बहुत कम है String। इसलिए, उपयोग करते समयnull जावा के संस्करण का करते थोड़ा अधिक सहज है।

हालांकि, उन दोनों ऑपरेटरों को सही होने पर पूरे पदानुक्रम के रूप में अच्छी तरह से देखने के लिए कहा जाता है। उदाहरण के लिए। यदि उदाहरण ए Stringहै Object। और यहाँ यह जावा है कि थोड़ा कम सहज है (क्योंकि एक उदाहरण वास्तव में एक, बहुत विशिष्ट प्रकार है) और सी # isअधिक सहज है (क्योंकि हर String एक एकObject गहरी अंदर)।

नीचे पंक्ति: यदि आप एक शब्द में बहुत उन्नत तर्क का वर्णन करने का प्रयास करते हैं, तो आप कुछ लोगों को भ्रमित करने के लिए बाध्य हैं, इस तरह या किसी अन्य। ऐसा लगता है कि अधिकांश लोग एक अर्थ पर सहमत थे और जो लोग सहमत नहीं थे, उन्हें समायोजित करना पड़ा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.