C# 中构造函数中的静态成员

本文关键字:静态成员 构造函数 | 更新日期: 2023-09-27 17:56:52

通常我们知道为了访问静态变量,我们不需要创建类的实例。我们可以直接做像classname.staticvariable.为了访问类中的静态变量,我们应该有一个静态方法。

现在我对以下代码片段有疑问

public class xyz
{
    private static int a;
    public xyz()
    {
        a++;
    }
}

上面的代码片段会起作用吗?如果是,为什么,如果不是为什么?

谢谢普拉班詹

C# 中构造函数中的静态成员

是的,会的。int 的默认值为 0。每次调用构造函数时,您都会增加静态变量。

引用有关静态变量的 C# 文档:

在访问静态成员之前初始化静态成员 第一次和在静态构造函数之前,如果有的话, 被称为。

例如,运行以下示例程序:

using System;
namespace ScrapCSConsole
{
   class ScrapCSConsole
   {
      public static void Main()
      {
         Console.WriteLine("Create StaticDemo A");
         StaticDemo a = new StaticDemo();
         Console.WriteLine("Create StaticDemo B");
         StaticDemo b = new StaticDemo();
         Console.WriteLine("Done");
      }
   }
   class StaticDemo
   {
      private static int staticDemo1;
      private static int staticDemo2 = 0;
      private static int staticDemo3 = default(int);
      private static int staticDemo4;
      private static int classNumber;
      /// <summary>
      /// Static Constructor
      /// </summary>
      static StaticDemo()
      {
         Console.WriteLine("Static Constructor");
         Console.WriteLine("staticDemo1 {0}", staticDemo1);
         staticDemo4 = (new DateTime(1999, 12, 31)).DayOfYear;
      }
      /// <summary>
      /// Instance Constructor
      /// </summary>    
      public StaticDemo()
      {
         classNumber++;
         Console.WriteLine("classNumber {0}", classNumber);
         Console.WriteLine("staticDemo2 {0}", staticDemo2);
         Console.WriteLine("staticDemo3 {0}", staticDemo3);
         Console.WriteLine("staticDemo4 {0}", staticDemo4);                  
      }      
   }
}

你会得到以下输出:

Create StaticDemo A
Static Constructor 
staticDemo1 0
classNumber 1
staticDemo2 0
staticDemo3 0
staticDemo4 365
Create StaticDemo B
classNumber 2
staticDemo2 0
staticDemo3 0
staticDemo4 365
Done

这里有一些有趣的事情需要注意:

  1. "Console.WriteLine("Create StaticDemo A")"行在 StaticDemo 的静态构造函数之前调用。
  2. "Console.WriteLine("静态构造函数")"行只被调用一次。
  3. "Console.WriteLine("staticDemo1 {0}", staticDemo1
  4. )"行有效,即使 staticDemo1 从未显式初始化过。
  5. staticDemo1、staticDemo2 和 staticDemo 3 的值都以 0 开头。

最后,作为子注释,如果要在多个线程上创建对象,则需要小心。这是因为classNumber++不是原子操作。它计为两个单独的操作,一个读取和一个写入。因此,两个单独的线程都可以在其中一个线程写出递增的值之前读取变量。要避免这种情况,请改用此行:

System.Threading.Interlocked.Increment(ref classNumber);

它有效。

假设您想知道已经创建了一个类的多少个实例。所以在这种情况下,您可以使用

xyz.a 

此外,要监视活动实例的数量,您可以创建析构函数并使用 a--

从实例方法访问静态成员是完全可以的。

静态变量 a 的默认值为 0,每次创建类的实例时,代码都会递增该值。

上面的代码片段将完美运行。编写此类代码是为了计算类存在的活动实例数。

public class xyz
{
    private static int a;
    public xyz()
    {
        a++;
    }
    public static int A
    {
        get { return a;}
    }
}

将活动实例数打印为:

Console.WriteLine(obj.A);

以下假设是不正确的;

为了访问类中的静态变量,我们应该有 静态方法。

提供的代码有效,因为您不需要静态方法。

尝试以下操作,您将看到它也可以工作;

public class xyz
{
    private static int a;
    public void A()
    {
        a++;
    }
}

是的,它会起作用。可以在实例成员中引用静态成员,但不能引用静态成员中的实例成员,因为它们需要实例才能工作,而静态不需要。

它不起作用如果要访问静态 var,则必须将其标记为公共和构造函数方法不运行,因为构造函数在你使用初始化类和创建对象时运行。