c#取消赋值的静态int结果为0

本文关键字:结果 int 静态 取消 赋值 | 更新日期: 2023-09-27 18:05:45

在实验静态变量时,我惊讶地知道为什么静态"int"结果为0(零)而非静态结果为编译时错误。

考虑案例1

  static int i;
  static void Main()
  {
     Console.Write("Value of i = " + i);
     Console.ReadKey();
  }

输出为

 Value of i = 0

去掉静态

的情形2
  static void Main()
  {
     int i;
     Console.Write("Value of i = " + i);
     Console.ReadKey();
  }

这个输出将导致编译时错误

  Error 1   Use of unassigned local variable 'i'

问题是这两种情况如何不同,即第一个结果为0,另一个得到编译错误。

c#取消赋值的静态int结果为0

现有的答案都遗漏了一些重要的东西,这就是变量声明的地方。它是类变量还是局部变量

第一个场景

class Program
{
    static int i;
    static void Main()
    {
       Console.Write("Value of i = " + i);
       Console.ReadKey();
    }
}

变量i被声明为类变量。类变量总是被初始化,不管它是否是静态的。如果不提供默认值,则将该变量赋值为default,在int的情况下为0。

另一方面,在第二个例子

class Program
{
    static void Main()
    {
        int i;
        Console.Write("Value of i = " + i);
        Console.ReadKey();
    }
}

变量i为局部变量。与类变量不同,局部变量永远不会隐式地初始化默认值,只有在显式初始化它们时才会初始化。因此,编译错误不是来自变量是否是静态的,而是来自局部变量和类变量初始化的差异。

规范分享了更多的细节:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/variables,特别是9.2变量类型和9.3默认值。有趣的部分是

静态变量的初始值是该变量类型的默认值(第9.3节)。

9.3.2.2类的实例变量的初始值是该变量类型的默认值(第9.3节)。

由local_variable_declaration引入的局部变量不会自动初始化,因此没有默认值。这样的局部变量被认为是初始未赋值的。

9.3:以下类别的变量被自动初始化为默认值:

    静态变量。
  • 类实例的实例变量。
  • 数组元素。

这样做的根本原因与内存管理有关。当您用new()初始化一个类时,垃圾收集器将把堆上的所有字节归零,因此基本上默认了变量的值。对于整数,它是0,对于对象引用,它将是null

由于局部变量存在于堆栈上,而垃圾收集器不在堆栈上工作,因此不存在这种保证,因此在使用变量之前必须显式初始化变量

根据c#语言的定义,类型具有"默认值",如果您不分配其他值,则该值将被分配给它们。数字的默认值为0,布尔值为false,引用类型为null,结构类型为每个成员的类型。

根据我有限的理解,通过将变量声明为静态,它将在内存中存在并被分配默认值0,并且不依赖于它所处的类的实例来存在。

如果它不是定义为静态的,则需要在类中初始化(如给定值),然后才能在任何逻辑/数学中使用它。

现在我的困惑来自于非常新的,并试图理解为什么你会选择这样做,而不是另一种方式。也许这是一种保留一些值的方法,即使它所在的类不存在,也可能是必要的,并且使所有内容都是静态的将导致内存使用效率低下。