为啥 C# 公共静态变量不需要实例化?

Posted

技术标签:

【中文标题】为啥 C# 公共静态变量不需要实例化?【英文标题】:Why C# public static variable doesn't need instantiation?为什么 C# 公共静态变量不需要实例化? 【发布时间】:2021-11-23 13:38:52 【问题描述】:

我是一个裸机 C 微控制器人,现在正在钻研 OOP 领域,从 C# 和 C++ 开始。

    我知道,一个类的成员要被另一个类访问,它必须是存储类 static 并且访问说明符应该是 public。 另外,我可以从 class1 访问 class2 的公共静态变量(假设为 100),而无需创建 class 2 的对象/实例。 但要访问同一类的非静态成员 public 成员,必须实例化。

现在的问题:

    为什么即使没有实例化类,我们也可以访问公共静态变量? 静态变量是否为同一个类的两个不同对象/实例共享相同的内存空间(换句话说,它们没有区别)?

【问题讨论】:

【参考方案1】:

C# 有“静态构造函数”的概念。

这段代码:

public class Bar

    public static int Foo = 100;

等价于

public class Bar

    public static int Foo;
    static Bar()
    
        Foo = 100;
    

运行时保证类的静态构造函数总是在类或其任何成员第一次使用之前执行。这就是静态成员可以有默认值的原因。

【讨论】:

【参考方案2】:

男孩,我在 C++ 方面真的很弱,但让我根据我对 Objective-C 和 OOP 的理解来描述使用“C 概念”。

第一季度。答:因为公共静态变量在启动时在程序的单个全局变量内存空间中分配一次,而不是在任何特定对象的(堆分配的)内存空间中。对象的实例变量的内存位于创建(实例化)该对象时从堆分配的空间中。 (对象或多或少像 malloc() 的结构;实例变量是该结构的字段)。因此,您可以随时随地读写公共静态变量,不受任何对象(如果有)的生命周期的影响。

第二季度。 A:静态变量就像C中的全局变量一样。每个变量都有自己的内存位置并分配与其大小相对应的内存量。所以当然两个变量不能共享同一个内存位置。

请注意,如果公共静态变量本身是特定类的对象,则它可能更复杂且特定于语言;我相信 C++ 静态对象就像 C 中的全局结构一样。但不一定;如果对象在其实例变量(即“字段”)中包含其他对象,并且那些其他对象在其构造函数中做了一些棘手的事情,那么所有的赌注都没有了......

【讨论】:

【参考方案3】:

对于您的具体问题:


    为什么即使类没有实例化,我们也可以访问公共静态变量?

我会说你实例化对象而不是类,但这与结果无关。

静态成员属于类,不属于该类的任何特定对象。因此,无论您是否实例化该类的任何对象,它们都可以存在。

如果它们是私有的,您仍然需要实例化一个对象,因为只有该类的对象才能访问私有数据。但这是一个可访问性而不是存在的问题。

可以从类外部访问公共静态数据,因此无需实例化即可获取它们。


2/ 静态变量是否为同一个类的两个不同对象/实例共享相同的内存空间(换句话说,它们不是不同的)?

可以以这种方式实现静态,但效率会相当低。

给定一个静态成员属于该类,从允许更改它的任何地方更改它,必须在任何你能看到它的地方更改它。

因此,最有效的方法是拥有一个

【讨论】:

以上是关于为啥 C# 公共静态变量不需要实例化?的主要内容,如果未能解决你的问题,请参考以下文章

java:在java中为啥静态变量没有this引用?

Java静态方法,静态变量,初始化顺序

C#类的初始化顺序

C++ 为啥 Traits 在对象上不可用,而是作为静态成员变量可用

static静态变量

C#的静态类