我是否初始化整数变量有什么区别,例如:
int i = 0;
int i;
编译器或 CLR 是否将其视为同一件事?IIRC,我认为它们都被视为同一件事,但我似乎找不到这篇文章。
我是否初始化整数变量有什么区别,例如:
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的文章
正如以下链接所述,它们完全相同:
http://msdn.microsoft.com/en-us/library/aa664742%28VS.71%29.aspx
通过所有这些讨论,值得一提的是 C# 中的“default”关键字。
ieint i;
等价于int i = default(int);
which 等价于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
}
这里的各种回复有点误导,包括“编码恐怖”网站上的参考文章。
当配置为优化生成的代码时,编译器将优化您的代码以删除所有“不必要的”初始化。请注意,这是在“发布”模式下编译时的默认行为。
一方面,我认为初始化所有变量总是非常有用的。在调试模式下对性能的影响最小,在发布模式下不会受到影响,但是显式设置变量的好处对于将来维护代码的任何人来说都是巨大的,采用更好的“用代码记录代码”风格。我记得我的一位非常有经验的同事认为 Int32 的默认值是 Int32.MinValue 而不是 0。这些类型的混淆总是发生在代码中隐含的事情上,对我来说,在大多数情况下应该避免它们。
每当您在 C# 中创建类型时,它都会自动填充零。在类(引用类型)的情况下,这相当于一个空指针。因此,从技术上讲,任何时候使用类,以下内容都是相同的:
MyClass class;
MyClass class2 = null;
对于值类型(任何结构,包括 int/float/double/etc),类型以零传递,因此以下是等价的:
int i;
int j = 0;
但是,在一个方法中,编译器会在使用它之前检查您是否已为您的类型分配了一个值。如果您执行以下操作,编译器将抱怨:
int i;
Console.WriteLine{"{0}",i);
从技术上讲,上面应该没问题 - 但由于它是程序员错误的常见来源,编译器专门检查未分配的局部变量并抱怨。但是,这是编译时投诉,而不是 CLR 问题。您可以制作执行上述操作的 IL,并且它运行良好。
这些仅对字段(类变量)等效。初始化类时,字段会自动分配默认值。在方法或属性中,未分配的变量保持未分配状态,如果您尝试访问它的值,将导致编译器错误。