C# 静态类,方法,构造函数,字段

在C#中,静态表示无法实例化的内容。您不能创建静态类的对象,也不能使用对象访问静态成员。

类、变量、方法、属性、运算符、事件和构造函数可以使用static修饰符关键字定义为静态的。

静态类

在类名之前和访问修饰符之后应用static修饰符,使类成为静态的。下面定义了一个具有静态字段和方法的静态类。

public static class Calculator
{
    private static int _resultStorage = 0;
    
    public static string Type = "Arithmetic";

    public static int Sum(int num1, int num2)
    {
        return num1 + num2;
    }

    public static void Store(int result)
    {
        _resultStorage = result;
    }
}

上面的Calculator类是静态的。它的所有成员也是静态的。

您不能创建静态类的对象。因此,可以使用类名 ClassName.MemberName 直接访问static类的成员,如下所示。

class Program
{
    static void Main(string[] args)
    {
        var result = Calculator.Sum(10, 25); //调用静态方法
        Calculator.Store(result); 

        var calcType = Calculator.Type; // 访问静态变量
        Calculator.Type = "Scientific"; // 给静态变量赋值
    }
}

静态类规则

  1. 静态类无法实例化。

  2. 静态类的所有成员必须是静态的。否则,编译器将给出错误。

  3. 静态类可以包含静态变量,静态方法,静态属性,静态运算符,静态事件和静态构造函数。

  4. 静态类不能包含实例成员和构造函数。

  5. 索引器和析构器不能是静态的

  6. var不能用于定义静态成员。您必须在static关键字之后显式指定成员类型。

  7. 静态类是密封类,因此不能继承。

  8. 静态类不能从其他类继承。

  9. 可以使用 ClassName.MemberName(即:类名.成员名) 访问静态类成员。

  10. 静态类在程序所在的应用程序域的整个生命周期内都将保留在内存中。

非静态类中的静态成员

普通类(非静态类)可以包含一个或多个静态方法,字段,属性,事件和其他非静态成员。

使用一些静态成员定义非静态类,而不是将整个类声明为静态类,这是比较实用的。

静态字段

可以使用 static 关键字定义非静态类中的静态字段。

非静态类的静态字段在所有实例之间共享。因此,一个实例所做的更改将反映在其他实例中。

public class StopWatch
{
    public static int InstanceCounter = 0;
    // 实例构造函数
    public StopWatch()
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        StopWatch sw1 = new StopWatch();
        StopWatch sw2 = new StopWatch();
        Console.WriteLine(StopWatch.NoOfInstances); //2 
			
        StopWatch sw3 = new StopWatch();
        StopWatch sw4 = new StopWatch();
        Console.WriteLine(StopWatch.NoOfInstances);//4
    }
}

静态方法

您可以在非静态类中定义一个或多个静态方法。可以在不创建对象的情况下调用静态方法。您不能使用非静态类的对象调用静态方法。

静态方法只能调用其他静态方法并访问静态成员。您不能在静态方法中访问类的非静态成员。

class Program
{
    static int counter = 0;
    string name = "Demo Program";

    static void Main(string[] args)
    {
        counter++; // 可以访问静态字段
        Display("Hello World!"); // 可以调用静态方法

        name = "New Demo Program"; //错误:无法访问非静态成员
        SetRootFolder("C:\MyProgram"); //错误:无法调用非静态方法
    }

    static void Display(string text)
    {
        Console.WriteLine(text);
    }

    public void SetRootFolder(string path) {  }
}

静态方法规则

  1. 静态方法可以在返回类型之前使用 static 关键字定义,然后在访问修饰符之后定义。

  2. 静态方法可以重载,但不能被重写。

  3. 静态方法可以包含局部静态变量。

  4. 静态方法不能访问或调用非静态变量,除非它们被显式地作为参数传递。

静态构造函数

非静态类可以包含无参数静态构造函数。可以使用static关键字定义它,而没有访问修饰符,例如 public,private和protected。

以下示例演示了静态构造函数和实例构造函数之间的区别。

public class StopWatch
{
    // 静态构造函数
    static StopWatch()
    {
        Console.WriteLine("调用了静态构造函数");
    }

    // 实例构造函数
    public StopWatch()
    {
        Console.WriteLine("调用了实例构造函数");
    }

    // 静态方法
    public static void DisplayInfo()
    {
        Console.WriteLine("调用了DisplayInfo");
    }

    // 实例方法
    public void Start() { }

    // 实例方法
    public void Stop() {  }
}

上面的非静态类StopWatch包含一个静态构造函数,也包含一个非静态构造函数。

每当使用静态方法或首次创建实例时,静态构造函数仅被调用一次。下面的示例显示,在首次调用static方法时,将调用static构造函数。第二次再调用静态方法将不会调用静态构造函数。

StopWatch.DisplayInfo(); // 此处调用静态构造函数
StopWatch.DisplayInfo(); // 这里没有调用构造函数
输出:
已调用静态构造函数。
调用了DisplayInfo
调用了DisplayInfo

下面的示例显示,首次创建实例时将调用静态构造函数。

StopWatch sw1 = new StopWatch(); // 首先是静态构造函数,然后是实例构造函数 
StopWatch sw2 = new StopWatch();// 只有实例构造函数被调用 
StopWatch.DisplayInfo();
输出:
调用了静态构造函数
调用了实例构造函数
调用了实例构造函数
调用了DisplayInfo

静态构造函数规则

  1. 静态构造函数是使用 static 关键字定义的,没有使用访问修饰符 public,private 或 protected。

  2. 非静态类可以包含一个无参数的静态构造函数。不允许使用参数化的静态构造函数。

  3. 静态构造函数将在生命周期内仅执行一次。因此,如果在多个地方都使用了一个类,则无法确定何时在应用程序中调用它。

  4. 静态构造函数只能访问静态成员。它不能包含或访问实例成员。

静态成员存储在内存中称为“高频堆”的特殊区域中。非静态类的静态成员在该类的所有实例之间共享。因此,一个实例所做的更改将反映在所有其他实例中。