Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么必须初始化C#局部变量?_C#_Variables_Initialization - Fatal编程技术网

为什么必须初始化C#局部变量?

为什么必须初始化C#局部变量?,c#,variables,initialization,C#,Variables,Initialization,我正在阅读MCTS自定步调训练包(70-536)第2版,在第1章中,我们有以下内容 如何声明值类型变量 要使用类型,必须首先声明 作为该类型实例的符号。 值类型具有隐式 构造函数,所以声明它们 自动实例化类型; 你不必包括新的 关键字,就像您处理类一样。这个 构造函数指定一个默认值 (通常为null或0)到新的 例如,但你应该始终 显式初始化变量 在声明中,如中所示 以下代码块: 但是,当我编译以下控制台应用程序时 using System; using System.Collections.G

我正在阅读MCTS自定步调训练包(70-536)第2版,在第1章中,我们有以下内容

如何声明值类型变量 要使用类型,必须首先声明 作为该类型实例的符号。 值类型具有隐式 构造函数,所以声明它们 自动实例化类型; 你不必包括新的 关键字,就像您处理类一样。这个 构造函数指定一个默认值 (通常为null或0)到新的 例如,但你应该始终 显式初始化变量 在声明中,如中所示 以下代码块:

但是,当我编译以下控制台应用程序时

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ch1_70_536
{
    class Program
    {
        static void Main(string[] args)
        {
            bool b;
            Console.WriteLine("The value of b is " + b);
            Console.ReadKey();
        }
    }
}
我得到了编译时错误

“未分配局部变量b的使用”


它甚至没有在报告中提到。我做错了什么还是这本书完全错了?

您需要为
b

bool b = false;

除非你给它赋值,否则它是“未赋值的”

你需要先给b赋值,否则它不会被初始化

尝试:


b现在为false。

必须先分配局部变量,然后才能使用它们。但是,类字段将获得其默认值。

例如:

public bool MyMethod()
{
    bool a;

    Console.Write(a); // This is NOT OK.

    bool b = false;

    Console.Write(b); // This is OK.
}

class MyClass
{
    private bool _a;

    public void MyMethod()
    {
        Console.Write(_a); // This is OK.
    }
}
方法(方法作用域)中的变量需要显式初始化。类级别的变量(或“字段”)将使用默认值自动初始化

class Test
{
   bool b; // =false
   int i; // =0
}

此语句确实应该详细说明,以表明尽管可以在不为局部变量赋值的情况下声明该局部变量,但在为其赋值初始值之前,不能使用该局部变量:

构造函数为新实例分配一个默认值(通常为null或0),但您应该始终在声明中显式初始化变量


在C#和VB.net中扮演拇指的角色,在调用任何变量之前,先初始化它。 像


关于VB,这本书基本上是正确的,但在本例中,它没有提到VB和C#之间的区别

在VB中,所有局部变量都会自动初始化:

Sub Test()
  Dim x As Integer
  MessageBox.Show(x.ToString()) 'shows "0"
End Sub
而在C#中,局部变量没有初始化,编译器不允许您使用它们,直到它们:

void Test() {
  int x;
  MessageBox.Show(x.ToString()); // gives a compiler error
}
此外,还不清楚这本书中的引文实际上是在谈论局部变量还是类成员变量。在VB和C#中创建类实例时,始终初始化类成员变量

这本书说“值类型有一个隐式构造函数”是错误的。这根本不是事实。值类型初始化为其默认值(如果已初始化),并且在这种情况下不会调用构造函数。

在C#中,局部变量存储在堆栈中,编译器不会初始化它们以进行代码优化

所以这个引用,实际上甚至是值类型的指针,指向一个未定义的内存空间

因此,如果我们使用一个局部变量而没有将其设置为某个值,编译器就会知道我们将获得随机数据

下面是一个示例IL代码:

static void Test()
{
  int a;
  int b = 2;
}

.method private hidebysig static 
  void Test () cil managed 
{
  // Method begins at RVA 0x3044
  // Code size 4 (0x4)
  .maxstack 1
  .locals init (
    [0] int32 a,
    [1] int32 b
  )

  // (no C# code)
  IL_0000: nop
  // int num = 2;
  IL_0001: ldc.i4.2
  IL_0002: stloc.1
  // }
  IL_0003: ret
} // end of method Program::Test
Int32
在堆栈中的位置
0
a
定义,但未指定默认值

class Test
{
   bool b; // =false
   int i; // =0
}
所以它的值是不确定的,并且可以从存储单元中得到任何值


对于位置
1
处的
b
,稍后分配,一切正常。

感谢您的澄清。因此,正如Nick指出的,局部变量是初始化的,但是在我们显式地为它分配一个新值之前不能使用。正确吗?不,它们不是自动初始化的。这就是为什么您需要自己初始化它们。只有类字段会为您自动初始化@Nick谈到了类字段。我想你指的是声明的而不是初始化的。如果不给变量赋值,就不能初始化变量,初始化变量时就是这样做的。
void Test() {
  int x;
  MessageBox.Show(x.ToString()); // gives a compiler error
}
static void Test()
{
  int a;
  int b = 2;
}

.method private hidebysig static 
  void Test () cil managed 
{
  // Method begins at RVA 0x3044
  // Code size 4 (0x4)
  .maxstack 1
  .locals init (
    [0] int32 a,
    [1] int32 b
  )

  // (no C# code)
  IL_0000: nop
  // int num = 2;
  IL_0001: ldc.i4.2
  IL_0002: stloc.1
  // }
  IL_0003: ret
} // end of method Program::Test