[英]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.