8

在 C# 中,如果我执行以下操作:

int x;

然后按 F10,我看到 x 中存储了一个零。

但是当我尝试使用 x 时,它告诉我应该初始化它.. 为什么会这样?那里应该是零,对吧?

数组也是如此,所以:

int[]a = new int[5];

如果我们按 F10,我们会看到里面的所有整数都是零。

这是怎么回事 ?为什么我必须在 C# 中初始化一个变量,这与在 C++ 中不同?

4

5 回答 5

7

这是一个编译时错误,试图帮助您减少由于未初始化变量而导致的代码错误。很有用。

http://msdn.microsoft.com/en-us/library/4y7h161d(VS.80).aspx

更多阅读:

http://blogs.msdn.com/b/abhinaba/archive/2005/11/08/490248.aspx

关于禁用错误的一些话(你不能只是警告你 - 这不是警告):

http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/a073ccea-c43b-4536-be76-41949f0e2135

http://blogs.msdn.com/b/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx (证明是关于这个主题的最丰富的信息)

甚至更多讨论“localsinit” IL 标志(强制为本地设置默认值)与其与“双重赋值”的关系(C# 强制您编写int v=0,即使它已经存在)之间的关系。如果您想更深入地阅读 - ECMA-335 的第 I.12.2 节中定义的“localsinit”,请点击此处

于 2012-07-13T00:34:53.590 回答
4

简单地说,因为这就是 C# 的工作方式。来自 C# 语言规范:

5.3.2 最初未赋值的变量

以下类别的变量被归类为最初未分配:

· 最初未分配的结构变量的实例变量。

·输出参数,包括struct实例构造函数的this变量。

· 局部变量,在 catch 子句或 foreach 语句中声明的变量除外。

另一方面:

5.3.1 初始赋值变量

以下类别的变量被归类为最初指定的:

· 静态变量。

· 类实例的实例变量。

· 最初分配的结构变量的实例变量。

· 数组元素。

· 值参数。

· 参考参数。

· 在 catch 子句或 foreach 语句中声明的变量。

于 2012-07-13T00:37:27.863 回答
3

很简单……因为编译器坚持在使用局部变量之前先对其进行初始化。这可以防止与初始化失败相关的一整类错误。

如果您查看从以下几条语句生成的 IL:

int x;
Console.WriteLine("hello");
int y=5;
x=6;
Console.WriteLine(x+y);

您会看到以下内容:

//notice no ops related to x prior to console.writeline
IL_0000:  ldstr       "hello"
IL_0005:  call        System.Console.WriteLine
IL_000A:  ldc.i4.5    
IL_000B:  stloc.1        //create/store y
IL_000C:  ldc.i4.6    
IL_000D:  stloc.0        //x is really only created right here
IL_000E:  ldloc.0     
IL_000F:  ldloc.1     
IL_0010:  add         
IL_0011:  call        System.Console.WriteLine

如果您在将 x 存储到 IL 之前看到它的值,那么这是一个调试器技巧。

于 2012-07-13T00:34:52.013 回答
2

我相信自动初始化是一种运行时安全功能,而不是语言保证。碰巧.NET 会将变量归零,但这并不一定适用于每个框架。

请注意,对于数组,它是有保证的。

于 2012-07-13T00:36:26.537 回答
1

它为 0 只是运气,它可以是任何东西,这就是为什么你必须初始化它。

于 2012-07-13T00:34:03.437 回答