2015-08-28 12 views
12

मैं कुछ रुचि के साथ सी # 6 में जोड़े गए सुरक्षित नेविगेशन ऑपरेटर सुविधा का पालन कर रहा हूं। मैं थोड़ी देर के लिए इसके लिए तत्पर हूं। लेकिन मुझे उम्मीद से कुछ अलग व्यवहार मिल रहा है। मुझे एहसास है कि मैं वास्तव में समझ में नहीं आता कि यह वास्तव में कैसे काम करता है।सी # सुरक्षित नेविगेशन ऑपरेटर - वास्तव में क्या चल रहा है?

इस वर्ग

class Foo { 
    public int? Measure; 
} 

को देखते हुए यहाँ कुछ नया ऑपरेटर का उपयोग कोड है।

Foo f = new Foo { Measure = 3 }; 
Console.WriteLine(f?.Measure); // 3 

f = new Foo { Measure = null }; 
Console.WriteLine(f?.Measure); // null 

f = null; 
Console.WriteLine(f?.Measure); // null 

यहां तक ​​कि सब कुछ अपेक्षित काम कर रहा है। ?. सदस्यों तक पहुंच रहा है जब बाएं हाथ की ओर शून्य नहीं है, अन्यथा शून्य वापस आ रहा है। लेकिन यहां चीजें ऐसी दिशा में जाती हैं जिनकी मुझे उम्मीद नहीं थी।

var i = f?.Measure; // i is Nullable<int> 
Console.WriteLine(i.HasValue); // false 
Console.WriteLine(f?.Measure.HasValue); // null 

क्या?

i से मुझे HasValue क्यों मिल सकता है, लेकिन उसी अभिव्यक्ति से नहीं जिसे मैंने i पर असाइन किया था? HasValue कभी शून्य कैसे हो सकता है?

संपादित करें: मेरा वास्तविक प्रश्न प्रोग्राम व्यवहार के बारे में है, संकलन त्रुटि नहीं। मैंने संकलन के बारे में अतिरिक्त सामान हटा दिया, और इस सवाल को और अधिक संकीर्ण रूप से केंद्रित किया कि क्यों दो अलग-अलग परिणाम उसी तर्क की तरह दिखते हैं।

+0

के संभावित डुप्लिकेट [अमान्य सशर्त ऑपरेटर नल प्रकार के साथ काम नहीं कर रहा?] (Http://stackoverflow.com/questions/31811392/null-conditional-operator-not-working-with-nullable-types) – shf301

+0

कि सवाल संकलन त्रुटियों के बारे में है। चूंकि मेरा वास्तविक प्रश्न संकलन त्रुटियों के बारे में नहीं है, लेकिन कार्यक्रम व्यवहार, मैंने इस सवाल को मेरे प्रभाव को स्पष्ट किया है। – recursive

उत्तर

9

चलिए इस तर्क से चलते हैं।

var f = ???; 
var i = f?.Measure; 
var t = i.HasValue; 

हम नहीं जानते कि f शून्य है या नहीं।
1. यदि f अशक्त, तो परिणाम है (i) है null
2. यदि f अशक्त, परिणाम नहीं है तो (i) एक int

इसलिए है, i के रूप में परिभाषित किया गया है int?, और t एक bool

है अब, चलो इस के माध्यम से चलना है:

var f = ???; 
var i = f?.Measure.HasValue; 
  1. तो f रिक्त है, तो परिणाम (i)
  2. तो f अशक्त, नहीं है तो परिणाम (i) Measure.HasValue है, जो एक bool है रिक्त है।

इसलिए, ibool? है।

यदि f शून्य है, तो हम शॉर्ट-सर्किट और शून्य लौटते हैं।यदि ऐसा नहीं है, तो हम bool.HasValue के परिणाम लौटाते हैं।

अनिवार्य रूप से, जब ?. का उपयोग कर - वापसी प्रकार एक संदर्भ मूल्य, या एक Nullable<T> होना चाहिए, के रूप में अभिव्यक्ति शॉर्ट सर्किट अशक्त लौटने के लिए कर सकते हैं।

+1

एचएम ... यह मेरे लिए दिमागी दबदबा है, लेकिन मुझे लगता है कि मैं उस व्यवहार को अनुकूलित कर सकता हूं। यह निश्चित रूप से अलग है जो मैं उम्मीद कर रहा था। यदि यह काम करता है जैसा कि आप कहते हैं (और यह निश्चित रूप से लगता है!) तो 'f? .Measure'' f 'की "तार्किक उप-अभिव्यक्ति" नहीं है। .Measure.HasValue'। हो सकता है कि मैं थोड़ी देर के लिए इसके बारे में सोचने के बाद इसे इस तरह से पसंद करूंगा, लेकिन अभी के लिए, यह कारण के लिए कठिन लगता है। – recursive

+0

मैं मानता हूं कि यह पहले थोड़ा सा अंतर्ज्ञानी है। आप अभिव्यक्ति को "अगर एफ शून्य के रूप में पढ़ सकते हैं, वापस शून्य कर सकते हैं। अगर एफ शून्य नहीं है, तो मुझे बताएं कि क्या माप का मूल्य है"। मुझे लगता है कि कुछ उपयोग करने के लिए बस लेता है। एहसास करने की मुख्य बात यह है कि आप इसे पढ़ रहे हैं और समझ रहे हैं: 'f? .Measure.HasValue' इस प्रकार: '(f? .Measure) .HasValue', जो यह नहीं है - कैसे' var i = 1 + 2; var t = i * 3; 'var i = 1 + 2 * 3;' – Rob

+0

से अलग है यह एक सहायक तुलना है, लेकिन उस उदाहरण में, कम से कम '2 * 3' का मान है! मैंने माना होगा कि सही-सदस्यीय एक्सेसर पहले संभवतः लागू नहीं हो सका, क्योंकि बाएं को लागू होने तक इसे लागू करने के लिए कुछ भी नहीं है। दूसरे शब्दों में, '2' अपने आप पर एक बिल्कुल सही मूल्य है, लेकिन 'माप' केवल एक विशेष 'फू' के संबंध में समझ में आता है। – recursive

0

Nullable<T> वास्तव में एक संरचना है और इसलिए शून्य नहीं हो सकता है, केवल Value कर सकते हैं, इसलिए HasValue हमेशा पहुंच योग्य रहेगा।

+0

निश्चित रूप से, यह सुलभ है, जैसा कि मैंने अपने प्रश्न में दिखाया था। हालांकि, इसका मूल्य रहस्यमय रूप से 'झूठी' से 'शून्य' में बदल जाता है। – recursive

0
var i = f?.Measure; // i is Nullable<int> 
Console.WriteLine(i.HasValue); // false 
Console.WriteLine(f?.Measure.HasValue); // null 

इस मामले में, एफ शून्य है।

कारण i.HasValuefalse लौटाया गया है क्योंकि iNullable<int> प्रकार है। तो जब भी i का मान शून्य है, इस मामले में, i.HasValue अभी भी पहुंच योग्य है।

हालांकि, f?.Measure.HasValuef? के बाद तुरंत null लौटाता है। इसलिए परिणाम आप उपरोक्त देखते हैं। इस रूप में च .Measure.HasValue:

बस Rob's comment उद्धृत करने के लिए:

मुख्य बात को एहसास है कि आप पढ़ रहे हैं और समझने है? (? च .Measure) .HasValue, जो यह नहीं है।

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