Felipe Miosso
Felipe Miosso

Reputation: 7339

Is there any difference between declaring and initializing over return code directly?

Is there any difference between:

public CustomObject MyMethod() 
{
    var myObject = new CustomObject();
    return myObject
}

public int MyIntMethod() 
{
    var myInt = 1;
    return myInt;
}

to this:

public CustomObject MyMethod() 
{
    return new CustomObject();
}

public int MyIntMethod() 
{
    return 1;
}

Does the compiler do something different? Like null checks or something like that?

Upvotes: 3

Views: 78

Answers (2)

Dan Wilson
Dan Wilson

Reputation: 4047

Does the compiler do something different? Like null checks or something like that?

It depends on whether you have enabled optimizations. Null checks are not performed by the compiler.

Production code is typically compiled with optimizations enabled, so it doesn't matter how you write the code.

With local variables you get:

IL_0000:  nop         
IL_0001:  ret         

MyMethod:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+CustomObject..ctor
IL_0006:  stloc.0     // myObject
IL_0007:  ldloc.0     // myObject
IL_0008:  stloc.1     
IL_0009:  br.s        IL_000B
IL_000B:  ldloc.1     
IL_000C:  ret         

MyIntMethod:
IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     // myInt
IL_0003:  ldloc.0     // myInt
IL_0004:  stloc.1     
IL_0005:  br.s        IL_0007
IL_0007:  ldloc.1     
IL_0008:  ret         

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

Without local variables you get:

IL_0000:  nop         
IL_0001:  ret         

MyMethod:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+CustomObject..ctor
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret         

MyIntMethod:
IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

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

With compiler optimizations on you get this no matter what:

IL_0000:  ret         

MyMethod:
IL_0000:  newobj      UserQuery+CustomObject..ctor
IL_0005:  ret         

MyIntMethod:
IL_0000:  ldc.i4.1    
IL_0001:  ret         

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

Upvotes: 1

Turrican
Turrican

Reputation: 597

Compiler talks by itself UPDATED : (compiled without optimizations, with optimizations the compiled code is identical, thanks for the comments.) :

public CustomObject MyMethod() 
{
    var myObject = new CustomObject();
    return myObject
}

            var myObject = new CustomObject();
01933516  mov         ecx,58413C4h  
0193351B  call        014D30F4  
01933520  mov         dword ptr [ebp-44h],eax  
01933523  mov         ecx,dword ptr [ebp-44h]  
01933526  call        01930D10  
0193352B  mov         eax,dword ptr [ebp-44h]  
0193352E  mov         dword ptr [ebp-3Ch],eax  
            return myObject;
01933531  mov         eax,dword ptr [ebp-3Ch]  
01933534  mov         dword ptr [ebp-40h],eax  
01933537  nop  
01933538  jmp         0193353A 

VS

public CustomObject MyMethod() 
{
    return new CustomObject();
}

            return new CustomObject();
00FD2E11  mov         ecx,4E70F48h  
00FD2E16  call        00A830F4  
00FD2E1B  mov         dword ptr [ebp-40h],eax  
00FD2E1E  mov         ecx,dword ptr [ebp-40h]  
00FD2E21  call        00FD0D10  
00FD2E26  mov         eax,dword ptr [ebp-40h]  
00FD2E29  mov         dword ptr [ebp-3Ch],eax  
00FD2E2C  nop  
00FD2E2D  jmp         00FD2E2F  

There are 11 assembly instructions on the first method vs 9 assembly instructions on the second one. There are more pointer memory operations.

Upvotes: 1

Related Questions