2016-11-16 58 views
3

是否有任何區別:這個直接聲明和初始化返回碼是否有區別?

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; 
} 

?像空檢查或類似的東西?本身

+0

恕我直言最好的檢查這個的方法是編譯並查看編譯器生成的中間語言代碼。但我認爲A方法聲明瞭兩個引用foreach和B方法只有一個。因爲回報是一個參考。 – Turrican

+0

正如@Turrican建議的那樣 - 查看使用ILDASM或調試器反彙編窗口生成的代碼。您可能會發現編譯器將第一個代碼優化爲與第二個代碼相同。 – PaulF

+0

Idk在'C#'中,但是在'Java'中,如果你設置了編譯器警告來詳細說明它會抱怨你的第一塊代碼,說明變量'myObject'是無用的,因此你應該直接返回值。這很可能同樣適用於'C#' – RafaelC

回答

0

編譯會談更新:(不優化編譯,以優化的編譯的代碼是相同的,感謝您的意見。):

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 

有11個彙編指令第一個方法與第二個方法的9個彙編指令。有更多的指針內存操作。

+0

除非啓用編譯器優化,否則這兩種方法都簡化爲相同的IL。 –

+0

當然,即使您*沒有這樣做,抖動也會執行這些優化。當然,除了所有這些問題,問他們是否有不同的行爲,而不是如果他們以不同的方式完成相同的功能。 – Servy

0

編譯器是否做了一些不同的事情?像空檢查或 類似的東西?

這取決於您是否啓用了優化。編譯器不執行空檢查。

產品代碼通常是在啓用優化的情況下進行編譯的,所以無論您如何編寫代碼都無關緊要。

隨着局部變量您可以:

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   
+0

這是什麼意思?可以從中得出什麼結論?請添加一些解釋以減輕理解 – RafaelC