C#变量的初始化问题
我看着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
正如下面的链接状态,它们是完全一样的:
http://msdn.microsoft.com/en-us/library/aa664742%28VS.71%29.aspx
仅当它们是字段(类成员)时才为true。 OP提到变量和名称也表明这一点。 – 2009-06-04 20:28:57
如果变量我是一个实例变量,它会被自动赋值为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
int是一个结构体而不是类。结构默认值为默认值,类为nul。 – 2009-06-04 19:19:28
@Mthethew Whited,他并不是说这是一堂课。他在班级“水平”上说,这实际上意味着实例变量。我为了澄清而编辑它。 – mmcdole 2009-06-05 03:59:02
创建在C#中的类型任何时候,它会自动获取与填充填充零。在类(引用类型)的情况下,这相当于一个空指针。因此,从技术上说,任何你和班工作时间,以下是相同的:
MyClass class;
MyClass class2 = null;
对于值类型(结构的任何,包括INT /浮点/双/等),类型与零通过,所以以下是等价的:
int i;
int j = 0;
然而,在方法,以查看编译器检查,如果你之前使用它分配一个值,你的类型。如果你做到以下几点,编译器会抱怨:
int i;
Console.WriteLine{"{0}",i);
技术上,上面的应该罚款 - 但因为它是程序员错误的常见原因,编译器专门检查未分配的局部变量和抱怨。但是,这是编译时投诉,而不是CLR问题。你可以让IL做到以上,并且运行良好。
这些仅仅是等效字段(类变量)。初始化类时,字段会自动分配默认值。在方法或属性中,未分配的变量保持未分配状态,如果尝试访问它的值,将导致编译器错误。
有了这些话题,值得一提的是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
}
各种反应是一种误导,包括日e参考文章在“编码恐怖”网站。
编译器会优化您的代码,以便在配置为优化生成的代码时删除所有“不必要的”初始化。请注意,这是在“Release”模式下编译时的默认行为。例如,我认为初始化所有变量总是非常有用。在调试模式下性能命中率最低,发布模式下性能最低,但对于任何未来维护代码的人来说,明确设置变量的收益将是巨大的,更好的是“用代码编写代码”风格。我记得我这个非常有经验的同事认为Int32的默认值是Int32.MinValue而不是0.这些类型的混淆总是发生在代码中的东西,对我而言,在大多数情况下应该避免这些混淆。
_Fields_始终自动初始化为字段类型的默认值,在int为零的情况下。字段被认为是明确分配的;你甚至可以在明确的任务之前阅读他们的内容。 _Locals_不被视为明确分配;在读取内容之前,您需要做一些分配本地值的内容。有关详细信息,请参阅C#规范的“明确赋值”部分。 – 2009-06-04 19:49:54