静态类不会先调用,而是实例类。为什么?

时间:2013-02-13 13:08:34

标签: c# .net static

我知道,静态构造函数始终优先,并在任何实例构造函数之前首先调用。但是请考虑我有一个实例类和一个静态类的场景。我想知道为什么结果首先来自Base类然后是静态类?我还验证了交换呼叫,我得到了相应的结果。但我的想法是错误的,静态类总是应该首先调用,而不管其他任何实例类?为什么这个问题是因为我看到某个地方,当触发包含该类的命名空间时,会自动加载静态类。然后我希望首先触发静态构造函数。为什么不发生?有人可以用一种可以理解和简单的方式解释。

    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();
    }

4 个答案:

答案 0 :(得分:1)

只有一个保证:

  

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

此保证没有说明调用静态构造函数的时间。大多数情况下,当实际使用静态类时,它将被调用 - 而不是更早。

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

你说:

  

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

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

MSDN声明如下:

  

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

我看到这怎么会被误解。这里“加载类”并不意味着它的构造函数被执行。这意味着CLR只需加载类型并对其执行一些验证。

答案 1 :(得分:1)

根据MSDN:

  

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

只有在实际需要时才调用静态构造函数。如果需要它们,则保证在它们的类的正常构造函数之前调用它们。

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

不可能这样做并避免调用未使用的静态构造函数。您可以在程序终止之前执行类似于仅使用静态构造函数访问类的操作,然后仅在满足某些条件时执行此操作。显然,代码无法及时查找以确定是否需要静态构造函数调用;因此,在代码访问之前,它无法调用静态构造函数。

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