2009-06-04 100 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.这些类型的混淆总是发生在代码中的东西,对我而言,在大多数情况下应该避免这些混淆。