c#6 null condition operator _c# Tutorial

Source: Internet
Author: User

1. The old version of the code

 Namespace CSHARP6
 {
  internal class person
  {public
   string Name {get; set;}
  }
 
  Internal class program
  {
   private static void Main ()
   {person person
   = null;
   string name = NULL;
   if (person!= null)
   {
    name = person. Name;}}}
 

When we use an object's properties, sometimes the first step is to determine whether the object itself is bull, or you may get a System.NullReferenceException exception. Although sometimes we can use the ternary operator string name = Person!= null? Person. Name:null to simplify the code, but it's not easy to write ... Because of the very common coding behavior in programming when null values are detected, SO,C#6 brings us a much simpler way.

2. Null condition operator

 Namespace CSHARP6
 {
  internal class person
  {public
   string Name {get; set;}
  }
 
  Internal class program
  {
   private static void Main ()
   {person person
    = null;
   String name = Person?. Name;}}
 }

From the above we can see that use? This approach can be used instead of if judgments and simplifying the use of ternary operators, simple to no more concise. By convention, the two IL codes are compared.

Old version of IL code:

. method private Hidebysig static void Main () cil managed
 {
 . entrypoint
 //Code size  (0x17)
 . Maxstack 2
 Locals init ([0] class CSHARP6. person person,
    [1] string name,
    [2] bool v_2)
 Il_0000:nop
 il_0001:ldnull
 il_0002:stloc.0
 Il_0003:ldnull
 Il_0004:stloc.1
 il_0005:ldloc.0
 il_0006:ldnull
 IL_0007:cgt.un
 il_0009:stloc.2
 il_000a : Ldloc.2
 il_000b:brfalse.s il_0016
 il_000d:nop
 il_000e:ldloc.0
 il_000f:callvirt String CSHARP6. Person::get_name ()
 il_0014:stloc.1
 il_0015:nop
 il_0016:ret
 }//End of method Program::main

If version of IL

Il of the new syntax:

. method private Hidebysig static void Main () cil managed
 {
 . entrypoint
 //Code size  (0x11)
 . Maxstack 1
 Locals init ([0] class CSHARP6. person person,
    [1] string name
 il_0000:nop
 il_0001:ldnull
 il_0002:stloc.0
 il_0003:ldloc.0< C12/>IL_0004:BRTRUE.S il_0009
 il_0006:ldnull
 il_0007:br.s  il_000f
 il_0009:ldloc.0
 000a:call  instance string csharp6. Person::get_name ()
 il_000f:stloc.1
 Il_0010:ret
 }//End of method Program::main

Il for null conditional operator version

Gee, there seems to be a big difference, let's have another ternary operator version of the Il look:

 . method private Hidebysig static void Main () cil managed
 {
 . entrypoint
 //Code size  (0x11)
 . Maxstack 1
 Locals init ([0] class CSHARP6. person person,
    [1] string name
 il_0000:nop
 il_0001:ldnull
 il_0002:stloc.0
 il_0003:ldloc.0< C12/>IL_0004:BRTRUE.S il_0009
 il_0006:ldnull
 il_0007:br.s  il_000f
 il_0009:ldloc.0
 000a:callvirt instance string csharp6. Person::get_name ()
 il_000f:stloc.1
 Il_0010:ret
 }//End of method Program::main

Il of ternary operator edition

New syntax "?." and the ternary operator "?:" The result is that the only difference is il_000a this line. "?." The way is compiled into call, and the "?:" Way is compiled into callvirt, somehow "?:" in the persion. Why is name compiled into a callvirt that supports polymorphic invocation, in which case it seems more efficient to call, but ultimately "?." and "?:" compiled code is not fundamentally different.

But it's simpler to compare to if judgments, and we analyze the IL to see what the differences are (ignoring the difference between call and callvirt):

Il analysis of the IF version:

Method private hidebysig static void Main () cil managed {. entrypoint. maxstack 2. Locals init ([0] class CSHARP6.       Person person,//initialize local variable person, place person at index 0 [1] string name,///Initialize local variable name, place name at index 1 [2] bool v_2) Initialize local variable v_2, place v_2 at index 2 IL_0000:NOP//null IL_0001:LDNULL//LOAD NULL il_0002:stloc.0//NULL
 The variable in index 0, which is the person object.
 Il_0003:ldnull//load NULL IL_0004:STLOC.1//drop NULL into a variable indexed to 1, which is the name object. il_0005:ldloc.0//Load the variable with index 0, that is, the person object il_0006:ldnull//Load null IL_0007:cgt.un//Compare the values loaded in the first two steps.
 If the first value is greater than the second value, the integer value of 1 is pushed onto the evaluation stack, and the 0 is pushed onto the evaluation stack instead. IL_0009:STLOC.2//Put the comparison into a variable indexed to 2, that is, the V_2 object IL_000A:LDLOC.2//Loading an object with an index of 2, that is, V_2 object Il_000b:brfalse.s il_00
 16//If the object loaded in the previous step is false, null reference, or 0, it jumps to the il_0016 position, which is the end of the current method. Il_000d:nop//Empty il_000e:ldloc.0//load the variable with index 0, which is the person object Il_000f:callvirt instance string csharp6.
 Person::get_name ()//calls the Get_name method of the Person object.  Il_0014:stloc.1      Save the results of the previous step in a variable indexed to 1, which is the name object.  Il_0015:nop//Empty Il_0016:ret//return}

Il analysis of the null conditional operator version:

 . method private Hidebysig static void Main () cil managed
 {
  . entrypoint
  . maxstack 1
  . Locals init ([0] Clas S CSHARP6. Person person,//initialize local variable person, place person at index 0
       [1] String name           //Initialize local variable name, place name at index 1 location
  il_0000: NOP                 //null
  il_0001:ldnull                //load null
  il_0002:stloc.0               //drop NULL into a variable indexed to 0, which is the person object
  Il_ 0003:ldloc.0               //Load the variable with index 0, that is, the person object
  il_0004:brtrue.s  il_0009          //If the object loaded in the previous step is true, Non-null, or Non-zero , then jump to il_0009 position
  il_0006:ldnull                //load null
  IL_0007:BR.S    il_000f          //unconditional jump to il_000f
  IL _0009:ldloc.0               //Loads the variable at the position of index 0, which is the person object
  Il_000a:call    instance string csharp6. Person::get_name ()////the Get_name method that invokes the person object.
  il_000f:stloc.1               //The result of the previous step is stored in a variable indexed to 1, which is the name object.
  Il_0010:ret                 //Return
 }

Through analysis we found that the null operator compiled IL code is shorter, using 2 branch jumps, simplifying the logic of judgment, and if version of Il more than a bool type of v_2 temporary variables.

So, the conclusion is "?." and ternary operator "?:" The compilation result is the same, and simplifies the judgment of If. So whether it's about performance or readability, "?." is the recommended wording.

3. Example 3.1? [

The null condition operator can use not only the?. Syntax to access the properties and methods of the object. The syntax accesses whether an object that detects an array or contains an indexer is null. Like what:

 person[] persons = NULL;
 //?.
 Int? Length = persons? Length;
 //? [Person I
 = persons? [0];

3.2?. Combine??

The persions above? The result returned by lenght is nullable type, and sometimes we may need an int type, then we can combine the null join operator "??" Use together, for example:

person[] persons = NULL;
//?. And?? Combined use
int length = persons?. Length?? 0;

3.3 Calling events in a thread-safe manner

 PropertyChangedEventHandler propertychanged = propertychanged;
 if (propertychanged!= null)
 {
 propertychanged (this, new PropertyChangedEventArgs (Nameof (Name));
 }

The above code is always the way we call events, and the reference to the event is placed in a temporary variable to prevent the event from being unregistered when the delegate is invoked, resulting in null.

We can finally invoke the event in a simpler way after c#6 (this ridge has continued since the C#1 era ...). ):

PropertyChanged? Invoke (PropertyChanged (This, new PropertyChangedEventArgs (Nameof (Name));

4. Summary

The null conditional operator is a syntax simplification, and it does a compilation optimization, and the optimization is consistent with the optimization of the ternary operator. The syntax is simpler and the performance is better, so why don't we use the new syntax?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.