直接声明和初始化返回代码有什么区别吗?

本文关键字:什么 区别 代码 返回 声明 初始化 | 更新日期: 2023-09-27 18:18:28

public CustomObject MyMethod() 
{
    var myObject = new CustomObject();
    return myObject
}
public int MyIntMethod() 
{
    var myInt = 1;
    return myInt;
}

:

public CustomObject MyMethod() 
{
    return new CustomObject();
}
public int MyIntMethod() 
{
    return 1;
}

编译器做一些不同的事情吗?比如空头支票之类的?

直接声明和初始化返回代码有什么区别吗?

编译器做一些不同的事情吗?比如空头支票类似的东西?

这取决于您是否启用了优化。编译器不执行空检查。

产品代码通常是在启用优化的情况下编译的,所以如何编写代码并不重要。

对于局部变量,您得到:

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         

如果没有局部变量,你会得到:

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         

在编译器优化的情况下,无论如何你都会得到这个:

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         

编译器自己说话更新:(编译没有优化,优化编译的代码是相同的,感谢评论。):

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 

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  

第一种方法有11条汇编指令,第二种方法有9条汇编指令。有更多的指针内存操作。