簡體   English   中英

C#變量初始化問題

[英]C# Variable Initialization Question

我是否初始化整數變量是否有任何區別:

int i = 0;
int i;

編譯器或CLR是否將此視為同一個東西? IIRC,我認為他們都被視為同一件事,但我似乎無法找到這篇文章。

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

例如:

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

以上將無法編譯,因為i2未分配。 但是,通過將0分配給i2,即

int i2 = 0;

並編譯,然后運行,將顯示兩者現在分配為0。

我查看了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

是的,它幾乎是一回事。

你可以參考這篇關於Coding Horror的文章

這里的各種回應都有誤導性,包括“編碼恐怖”網站中引用的文章。

當配置為優化生成的代碼時,編譯器將優化您的代碼以刪除所有“不必要的”初始化。 請注意,這是在“發布”模式下編譯時的默認行為。

我認為,初始化所有變量總是非常有用。 在調試模式下,性能命中率最低,在發布模式下沒有,但是對於未來維護代碼的任何人來說,明確設置變量的好處將是巨大的,在更好的“帶代碼的文檔代碼”樣式中。 我記得我非常有經驗的同事認為Int32的默認值是Int32.MinValue而不是0.這些類型的混淆總是發生在代碼中的含義中,對我來說,在大多數情況下應該避免它們。

如下面的鏈接所述,它們完全相同:

http://msdn.microsoft.com/en-us/library/aa664742%28VS.71%29.aspx

通過所有這些討論,值得一提的是C#中的“default”關鍵字。

就是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
}

每次在C#中創建一個類型時,它都會自動填充填充的零。 在類(引用類型)的情況下,這相當於空指針。 因此,從技術上講,每當您使用類時,以下內容都是相同的:

MyClass class;
MyClass class2 = null;

使用值類型(任何結構,包括int / float / double / etc),類型以零傳遞,因此以下是等效的:

int i;
int j = 0;

但是,在方法中,編譯器會在使用之前檢查您是否為類型指定了值。 如果您執行以下操作,編譯器將抱怨:

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

從技術上講,上面應該沒問題 - 但由於它是程序員錯誤的常見來源,編譯器專門檢查未分配的局部變量,並抱怨。 但是,這是一個編譯時投訴,而不是CLR問題。 你可以讓IL做上面的事情,它運行正常。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM