2016-01-25 2 views
8

शून्य-सशर्त ऑपरेटर डुप्लिकेट नल चेक का उपयोग करता है?क्या नल-सशर्त ऑपरेटर निरंतर उपयोग साइटों पर अनुकूलित है या क्या इसका परिणाम डुप्लिकेट चेक में होता है?

if (instance != null) 
{ 
    var x = instance.Property1; 
    var y = instance.Property2; 
} 

या यह है: उदाहरण के

var x = instance?.Property1; 
var y = instance?.Property2; 

के लिए है कि इस में संकलित हो रहा है?

if (instance != null) 
{ 
    var x = instance.Property1; 
} 

if (instance != null) 
{ 
    var y = instance.Property2; 
} 

पूर्व है, यह एक फर्क पड़ता है अगर वहाँ दोनों लाइनों के बीच में अन्य कोड है? दूसरे शब्दों में, संकलक/अनुकूलक कितना स्मार्ट है?

+3

इतनी सारी नई विशेषताएं, लेकिन मैं अभी भी अपने गैर-नल प्रकारों की प्रतीक्षा कर रहा हूं। * साई *। – user2864740

+0

@ user2864740 सुनें –

उत्तर

6

संकलक इस बारे में काफी अज्ञानी प्रतीत होता है।

कोड:

var x = instance?.Property1; 
var y = instance?.Property2; 

... के रूप में संकलित करने के लिए गैर-अनुकूलित:

IL_0000: newobj  UserQuery+Class..ctor 
IL_0005: dup   
IL_0006: dup   
IL_0007: brtrue.s IL_000C 
IL_0009: pop   
IL_000A: br.s  IL_0012 
IL_000C: ldfld  UserQuery+Class.Property1 
IL_0011: pop   
IL_0012: dup   
IL_0013: brtrue.s IL_0017 
IL_0015: pop   
IL_0016: ret   
IL_0017: ldfld  UserQuery+Class.Property2 
IL_001C: pop   
IL_001D: ret   

Class..ctor: 
IL_0000: ldarg.0  
IL_0001: call  System.Object..ctor 
IL_0006: ret   

दोनों स्पष्ट रूप से दो के साथ:

IL_0000: nop   
IL_0001: newobj  UserQuery+Class..ctor 
IL_0006: stloc.0  // instance 
IL_0007: ldloc.0  // instance 
IL_0008: brtrue.s IL_000D 
IL_000A: ldnull  
IL_000B: br.s  IL_0013 
IL_000D: ldloc.0  // instance 
IL_000E: ldfld  UserQuery+Class.Property1 
IL_0013: stloc.1  // x 
IL_0014: ldloc.0  // instance 
IL_0015: brtrue.s IL_001A 
IL_0017: ldnull  
IL_0018: br.s  IL_0020 
IL_001A: ldloc.0  // instance 
IL_001B: ldfld  UserQuery+Class.Property2 
IL_0020: stloc.2  // y 
IL_0021: ret   

Class..ctor: 
IL_0000: ldarg.0  
IL_0001: call  System.Object..ctor 
IL_0006: nop   
IL_0007: ret   

... और के रूप में अनुकूलित करने के लिए शाखा की जांच

+0

हाय, यह बहुत अच्छा है! :) ऑफ-विषय, लेकिन मुझे आश्चर्य है कि आप उस प्रारूप में आईएल कैसे प्राप्त करते हैं? – Ian

+3

@Ian लगभग निश्चित रूप से LINQPad से :) – Rob

+0

@Rob हाय, दिशा के लिए धन्यवाद! : DI ने इस पर स्वीकृत उत्तर पढ़ा: http://stackoverflow.com/questions/3326571/how-can-i-view-msil-cil-generated-by-c-sharp-compiler-why-is-it-called -एसेम्ब और पीई फ़ाइल में '.text' द्वारा इसका क्या अर्थ है इसका पता लगाने की कोशिश कर रहा है। लेकिन अगर असेंबली कोड को देखने का कोई वैकल्पिक तरीका है (जैसा कि लिंक शो में दूसरा जवाब है) तो मैं बस जाऊंगा और उसे देखूंगा। :) – Ian

5

यह दो अलग है यदि आपके मामले में शून्य सशर्त ऑपरेटर का उपयोग करके असाइनमेंट के लिए जांच करता है। नीचे एक disassembled नमूना कोड है

स्रोत कोड:

public class nulltest 
{ 
    public void test() 
    { 
     var instance = new testclass(); 
     var x = instance?.prop1; 
     var y = instance?.prop2; 
    } 
} 

public class testclass 
{ 
    public int prop1; 
    public int prop2; 
} 

disassembled कोड (ILSpy):

public class nulltest 
{ 
    public void test() 
    { 
     testclass testclass = new testclass(); 
     if (testclass == null) 
     { 
      int? arg_20_0 = null; 
     } 
     else 
     { 
      new int?(testclass.prop1); 
     } 
     if (testclass == null) 
     { 
      int? arg_3A_0 = null; 
     } 
     else 
     { 
      new int?(testclass.prop2); 
     } 
    } 
} 

मैं संपत्ति के प्रकार के रूप int थे, लेकिन ऊपर किसी भी के लिए सच धारण करना चाहिए अन्य मामला

5

संकलक कठोर है, इस कोड के बारे में सोचो।

class Tricky 
{ 
    public int Property1 
    { 
     get 
     { 
      Program.instance = null; 
      return 1; 
     } 
    } 

    public int Property2 
    { 
     get 
     { 
      return 2; 
     } 
    } 
} 

class Program 
{ 
    public static Tricky instance = new Tricky(); 

    public static void Main(string[] arg) 
    { 
     var x = instance?.Property1; 
     var y = instance?.Property2; 
     //what do you think the values of x,y 
    } 
} 

अपेक्षित परिणाम है: x == 1, y is null। लेकिन यदि संकलक एक if कथन का उपयोग करके कोड को अनुकूलित करता है, तो यह NullReferenceException फेंकता है। जिसका अर्थ है, एक if कथन का उपयोग करना, एक स्मार्ट अनुकूलन नहीं है, यह अनुकूलन नहीं है, क्योंकि यह गलत है।

+0

लेकिन आप जानते हैं कि कोई भी इस तरह कोड लिखता है, है ना? ओह रुको ... –

+0

@NelsonRothermel True। हालांकि, एक कंपाइलर को इस तरह की धारणाओं के तहत काम नहीं करना चाहिए, उपर्युक्त कोड भाषा दृश्य से शुद्ध कानूनी है। –

+0

धागे की सुरक्षा का जिक्र नहीं है। –

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