【问题标题】:Static class doesn't get called first but instance class. Why?静态类不会首先被调用,而是实例类。为什么?
【发布时间】:2013-02-13 13:08:33
【问题描述】:

我知道,静态构造函数总是优先并在任何实例构造函数之前被首先调用。但是考虑一下我有一个实例类和一个静态类的情况。我想知道为什么结果首先来自基类,然后是静态类?我也验证了交换调用,我得到了相应的结果。但是我的想法是错误的吗,无论任何其他实例类如何,都应该首先调用静态类?为什么向我提出这个问题是因为,我在某处看到,当触发包含该类的命名空间时,会自动加载静态类。然后我希望该静态构造函数首先触发。为什么没有发生呢?有人可以以易于理解和简单的方式解释。

    public class Base
    {
        public Base() { Console.WriteLine(" I am from normal Base constructor"); }
        static Base() { Console.WriteLine("Hey I am from Static Base"); } 
    }
    public static class Base1
    {
        static Base1() { Console.WriteLine("I am from Static Constructor"); }
        public static void StaticMethod() { Console.WriteLine("I am from Static Method");   }            
    }

    static void Main(string[] args)
    {
        Base b = new Base();
        Base1.StaticMethod();
        Console.Read();
    }

【问题讨论】:

  • 你在哪里读到静态类是在触发包含该类的命名空间时自动加载的?
  • “我在某处看到,当触发包含该类的命名空间时,会自动加载静态类。”你如何“触发”一个命名空间?这根本不符合逻辑。请张贴神秘“某处”的链接,不清楚它们的意思。
  • 嗨 Blam 和 dasb,如果我误解了,请见谅,但您可以在 MSDN msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx 中看到类似的声明
  • 该链接确实显示“当加载包含该类的程序或命名空间时,.NET Framework 公共语言运行时 (CLR) 会自动加载静态类。”
  • 嗯,是的。老实说,我还是不明白这个说法。我理解下面有人解释的方式,但我很难理解 MSDN 在上述声明中试图传达的内容。

标签: c# .net static


【解决方案1】:

根据 MSDN:

静态构造函数用于初始化任何静态数据,或 执行只需要执行一次的特定操作。这是 在创建第一个实例或任何其他实例之前自动调用 静态成员被引用。

所以在你的情况下 - 首先你调用 Base 类构造函数,然后你访问 Base1 静态方法。

【讨论】:

    【解决方案2】:

    只有一种保证:

    类的静态构造函数在任何实例构造函数或该类的任何静态成员之前调用。

    这个保证没有说明调用静态构造函数的时间。大多数情况下,它会在实际使用静态类时被调用——而不是更早。

    在创建另一个类的实例之前,没有理由执行静态构造函数。

    你说:

    我在某处看到,当触发包含该类的命名空间时,会自动加载静态类。

    这不正确,我想你可能误解了那里的一些东西。

    MSDN 声明如下:

    当加载包含该类的程序或命名空间时,.NET Framework 公共语言运行时 (CLR) 会自动加载静态类。

    我明白这怎么可能被误解。这里的“加载一个类”并不意味着它的构造函数被执行。这意味着 CLR 只是加载类型并对其执行一些验证。

    【讨论】:

    • 非常感谢,是的,我可能误解了 MSDN 中给出的声明 :( 大多数时候我对 MSDN 的解释不太满意。msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
    • 哦,现在你的解释让我理解了 MSDN 的声明。我想,加载意味着,也解雇了构造函数。非常感谢您向我解释 :) :)
    【解决方案3】:

    仅在实际需要时才调用静态构造函数。如果需要它们,则保证在其类的普通构造函数之前调用它们。

    但不能保证所有静态构造函数都会在不同类的任何普通构造函数之前被调用。

    不可能这样做并且避免调用未使用的静态构造函数。你可以做一些事情,比如只在程序终止之前使用静态构造函数访问一个类,然后只有在满足某些条件的情况下。显然,代码无法及时确定是否需要调用静态构造函数;因此,它无法在您的代码访问它之前调用静态构造函数。

    查看Eric Lippert's Blog about Static Constructors了解更多详情!

    【讨论】:

    • 非常感谢马修,这对我有帮助。
    【解决方案4】:

    在您创建类的实例或访问其静态方法之一 (http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx) 之前调用静态构造函数,因此您得到的结果是正确的。

    【讨论】:

      猜你喜欢
      • 2011-05-30
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2020-09-29
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 1970-01-01
      相关资源
      最近更新 更多