2009-06-04 137 views
12

是否有關於我是否像初始化整數變量任何區別:C#變量的初始化問題

int i = 0; 
int i; 

該編譯器或CLR把這當作一回事嗎? IIRC,我認爲他們都被視爲同樣的事情,但我似乎無法找到文章。

+11

_Fields_始終自動初始化爲字段類型的默認值,在int爲零的情況下。字段被認爲是明確分配的;你甚至可以在明確的任務之前閱讀他們的內容。 _Locals_不被視爲明確分配;在讀取內容之前,您需要做一些分配本地值的內容。有關詳細信息,請參閱C#規範的「明確賦值」部分。 – 2009-06-04 19:49:54

回答

6

我看着IL(使用ildasm),它的真實性是隻有int設置爲0在構造函數中真的被設置爲0。

public class Class1 
{ 
    int setToZero = 0; 
    int notSet; 
} 

生成:

.method public hidebysig specialname rtspecialname 
     instance void .ctor() cil managed 
{ 
    // Code size  15 (0xf) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: ldc.i4.0 
    IL_0002: stfld  int32 ClassLibrary1.Class1::setToZero 
    IL_0007: ldarg.0 
    IL_0008: call  instance void [mscorlib]System.Object::.ctor() 
    IL_000d: nop 
    IL_000e: ret 
} // end of method Class1::.ctor 
4

是的,它幾乎是一回事。

你可以參考這篇文章Coding Horror

+0

+1。關於這個話題的有趣討論。 – CAbbott 2009-06-04 19:18:05

14

如果變量是一個實例變量,它會被自動賦值爲0。如果它是方法中的局部變量,則它是未定義的,因此在使用它之前需要爲其分配一個值。

例如:以上不能編譯,因爲I2是未分配

class Program 
{ 
    static void Main(string[] args) 
    { 
     intTest it; 

     it = new intTest(); 

     Console.ReadLine(); 
    } 

    class intTest 
    { 
     int i; 

     public intTest() 
     { 
      int i2; 

      Console.WriteLine("i = " + i); 
      Console.WriteLine("i2 = " + i2); 
     } 
    } 
} 

。然而,通過分配0到I2,即

int i2 = 0; 

和編譯,然後運行後,會表明,無論是現在賦值爲0

+0

int是一個結構體而不是類。結構默認值爲默認值,類爲nul。 – 2009-06-04 19:19:28

+0

@Mthethew Whited,他並不是說這是一堂課。他在班級「水平」上說,這實際上意味着實例變量。我爲了澄清而編輯它。 – mmcdole 2009-06-05 03:59:02

0

創建在C#中的類型任何時候,它會自動獲取與填充填充零。在類(引用類型)的情況下,這相當於一個空指針。因此,從技術上說,任何你和班工作時間,以下是相同的:

MyClass class; 
MyClass class2 = null; 

對於值類型(結構的任何,包括INT /浮點/雙/等),類型與零通過,所以以下是等價的:

int i; 
int j = 0; 

然而,在方法,以查看編譯器檢查,如果你之前使用它分配一個值,你的類型。如果你做到以下幾點,編譯器會抱怨:

int i; 
Console.WriteLine{"{0}",i); 

技術上,上面的應該罰款 - 但因爲它是程序員錯誤的常見原因,編譯器專門檢查未分配的局部變量和抱怨。但是,這是編譯時投訴,而不是CLR問題。你可以讓IL做到以上,並且運行良好。

0

這些僅僅是等效字段(類變量)。初始化類時,字段會自動分配默認值。在方法或屬性中,未分配的變量保持未分配狀態,如果嘗試訪問它的值,將導致編譯器錯誤。

1

有了這些話題,值得一提的是C#中的「默認」關鍵字。

I.e. int i;相當於int i = default(int);這相當於int i = 0;MyClass o = default(MyClass);相當於MyClass o = null;

使用LINQ的方法,如.SingleOrDefault()時候,因爲你總是可以使用以下方法來使你的代碼更易讀,這一點尤其重要:

int someValue = collection.<various linq methods>.SingleOrDefault(); 
if (someValue == default(int)) 
{ 
    //Code for the default case 
} 

這裏
MyClass someValue = collection.<various linq methods>.SingleOrDefault(); 
if (someValue == default(MyClass)) 
{ 
    //Code for the default case 
} 
0

各種反應是一種誤導,包括日e參考文章在「編碼恐怖」網站。

編譯器會優化您的代碼,以便在配置爲優化生成的代碼時刪除所有「不必要的」初始化。請注意,這是在「Release」模式下編譯時的默認行爲。例如,我認爲初始化所有變量總是非常有用。在調試模式下性能命中率最低,發佈模式下性能最低,但對於任何未來維護代碼的人來說,明確設置變量的收益將是巨大的,更好的是「用代碼編寫代碼」風格。我記得我這個非常有經驗的同事認爲Int32的默認值是Int32.MinValue而不是0.這些類型的混淆總是發生在代碼中的東西,對我而言,在大多數情況下應該避免這些混淆。