【问题标题】:Why C# local variables must be initialized?为什么必须初始化 C# 局部变量?
【发布时间】:2010-11-15 08:39:14
【问题描述】:

我正在阅读 MCTS 自定进度培训套件 (70-536) 第 2 版,在第 1 章中我们有以下内容。

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

'VB

Dim b As Boolean = False    

// C#  
bool b = false;

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

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 的使用”

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

【问题讨论】:

    标签: c# variables initialization


    【解决方案1】:

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

    一个例子:

    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.
        }
    }
    

    【讨论】:

    • 感谢您的澄清。因此,正如 Nick 指出的那样,局部变量已初始化,但不能使用,直到我们明确地为其分配一个新值。对吗?
    • 不,它们不会自动初始化。这就是您需要自己初始化它们的原因。只有类字段会自动为您初始化。 @Nick 谈论类字段。
    【解决方案2】:

    这本书在谈到 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# 中,类成员变量总是在创建类实例时初始化。

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

    【讨论】:

      【解决方案3】:

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

      尝试:

      bool b = false; 
      Console.WriteLine("The value of b is " + b); 
      

      b 现在是假的。

      【讨论】:

        【解决方案4】:

        你需要给b赋值

        bool b = false;
        

        在您为其分配一个值之前,它是“未分配的”

        【讨论】:

          【解决方案5】:

          方法(方法范围)中的变量需要显式初始化。类级别的变量(或“字段”)会自动使用默认值初始化。

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

          【讨论】:

            【解决方案6】:

            在 C# 和 VB.net 中让它成为 THUMB 的角色,在调用任何变量之前,先初始化它。 喜欢

            int myInt; // Simple Declaration and have no value in it 
            myInt= 32; // Now you can use it as there is some value in it..
            

            【讨论】:

              【解决方案7】:

              这句话确实应该详细说明,虽然一个局部变量可以声明而不给它赋值,但它不能使用直到它被赋值初始值:

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

              【讨论】:

              • 我认为您的意思是 declared 而不是 initialized。你不能在不给它赋值的情况下初始化一个变量,这就是你在初始化它时所做的。
              【解决方案8】:

              在 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 定义,但未分配默认值。

              所以它的值是不确定的,可以从记忆单元中取任何值。

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-05-31
                • 1970-01-01
                • 2012-01-16
                • 1970-01-01
                • 1970-01-01
                • 2015-05-22
                相关资源
                最近更新 更多