क्या इन दोनों लाइनों में अंतर है?
MyName = (s.MyName == null) ? string.Empty : s.MyName
या
MyName = s.MyName ?? string.Empty
क्या इन दोनों लाइनों में अंतर है?
MyName = (s.MyName == null) ? string.Empty : s.MyName
या
MyName = s.MyName ?? string.Empty
s.MyNameएक या दो बार मूल्यांकन करते हैं ।
diffहै
जवाबों:
अद्यतन: मैंने एक ब्लॉग पोस्ट लिखा है जो इस विषय पर अधिक गहराई से चर्चा करता है। http://www.codeducky.org/properties-fields-and-methods-oh-my/
आम तौर पर वे उसी परिणाम को वापस करेंगे। हालांकि, ऐसे कुछ मामले हैं जहां आप MyNameएक संपत्ति होने पर ध्यान देने योग्य मतभेदों का अनुभव करेंगे क्योंकि MyNameगेट्टर को पहले उदाहरण में दो बार निष्पादित किया जाएगा और केवल एक बार दूसरे उदाहरण में।
उदाहरण के लिए, आप MyNameदो बार निष्पादित करने से प्रदर्शन अंतर अनुभव कर सकते हैं :
string MyName
{
get
{
Thread.Sleep(10000);
return "HELLO";
}
}
या MyNameयदि MyNameआप स्टेटफुल हैं तो दो बार क्रियान्वयन से अलग परिणाम प्राप्त कर सकते हैं :
private bool _MyNameHasBeenRead = false;
string MyName
{
get
{
if(_MyNameHasBeenRead)
throw new Exception("Can't read MyName twice");
_MyNameHasBeenRead = true;
Thread.Sleep(10000);
return "HELLO";
}
}
या MyNameयदि MyNameआप एक अलग धागे पर बदला जा सकता है तो दो बार निष्पादित करने से अलग परिणाम प्राप्त कर सकते हैं :
void ChangeMyNameAsync()
{
//MyName set to null in another thread which makes it
//possible for the first example to return null
Task.Run(() => this.MyName = null);
}
string MyName { get; set; }
यहां बताया गया है कि वास्तविक कोड कैसे संकलित किया जाता है। पहले टर्नरी अभिव्यक्ति के साथ टुकड़ा:
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- first call
IL_000D: brfalse.s IL_0017
IL_000F: ldloc.0 // s
IL_0010: callvirt s.get_MyName <-- second call
IL_0015: br.s IL_001C
IL_0017: ldsfld System.String.Empty
IL_001C: call set_MyName
और यहाँ null-coalescing ऑपरेटर के साथ टुकड़ा है:
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- only call
IL_000D: dup
IL_000E: brtrue.s IL_0016
IL_0010: pop
IL_0011: ldsfld System.String.Empty
IL_0016: call s.set_MyName
जैसा कि आप देख सकते हैं कि टर्नरी ऑपरेटर के लिए संकलित कोड संपत्ति मूल्य प्राप्त करने के लिए दो कॉल करेगा, जबकि अशक्त-संचालक ऑपरेटर केवल 1 करेगा।
MyName = s.MyName ?? string.EmptyMyNameप्रॉपर्टी होने पर दो बार गैटर को अंजाम नहीं देगा । इसलिए यदि आप दो बार गेट्टर को निष्पादित नहीं करना चाहते हैं, तो आपको दूसरी पंक्ति का उपयोग करना चाहिए।
et_MyName, जो होना चाहिए set_MyName।
?:वास्तव में लंबे संस्करण का परिणाम हो सकता nullहै। यह अधिक सचित्र हो सकता है अगर "Value from other thread"ऊपर वास्तव में एक nullस्ट्रिंग था। फिर यह दिखाएगा कि परिणाम शून्य हो सकता है। यदि वस्तु getएग्रीकल्चर के पहले आह्वान पर एक स्ट्रिंग इंस्टेंस को वापस करने और केवल दूसरे इनवोकेशन पर नल को वापस करने का निर्णय लेती है, तो स्टेटफुल ऑब्जेक्ट के साथ भी ऐसा हो सकता है ।
यदि संपत्ति एक साधारण गेट्टर से अधिक है, तो आप पहले वाले के लिए गैर-शून्य मामले में दो बार एक फ़ंक्शन निष्पादित कर सकते हैं।
यदि संपत्ति एक राज्य वस्तु में है, तो संपत्ति के लिए दूसरा कॉल एक अलग परिणाम दे सकता है:
class MyClass
{
private IEnumerator<string> _next = Next();
public MyClass()
{
this._next.MoveNext();
}
public string MyName
{
get
{
var n = this._next.Current;
this._next.MoveNext();
return n;
}
}
public static IEnumerator<string> Next()
{
yield return "foo";
yield return "bar";
}
}
इसके अलावा, गैर-स्ट्रिंग मामले में, वर्ग अधिभार == को टर्नरी ऑपरेटर की तुलना में कुछ अलग करने के लिए हो सकता है। मुझे विश्वास नहीं है कि टर्नरी ऑपरेटर को ओवरलोड किया जा सकता है।
?:। मैंने कोई भाषा नहीं देखी है जो करती है।
हां, दोनों समान हैं, और यह अशक्त-संचालक है ।
यदि ऑपरेंड शून्य नहीं है, तो यह बाएं हाथ का ऑपरेंड देता है; अन्यथा यह दाहिने हाथ का ऑपरेंड लौटाता है।
अगर हम दक्षता की बात करें तो
string MyName = (s.MyName == null) ? string.Empty : s.MyName;
string MyName2 = s.MyName ?? string.Empty;
यदि मैं एक असेंबलर का उपयोग करता हूं तो मैं देख सकता हूं कि पहले बयान को संकलक द्वारा निष्पादित करने के लिए 19 बयानों की आवश्यकता है जबकि दूसरे कथन को निष्पादित करने के लिए केवल 12 बयानों की आवश्यकता है ।
हां, वे ऐसा ही करते हैं। ??अशक्त के लिए जाँच के लिए आशुलिपि है।
नहीं। दोनों एक ही काम कर रहे हैं। दूसरा कुशल है। अगर यह शून्य नहीं है, तो वास्तविक मूल्य लौटाता है। दाहिने हाथ की ओर का मूल्य वापस किया जाएगा।
इस http://msdn.microsoft.com/en-us/library/ms173224.aspx को देखें
उम्मीद है की यह मदद करेगा।