为什么我的基类静态构造函数没有被调用?

11

假设我有2个类:

public abstract class Foo
{
    static Foo()
    {
        print("4");
    }
}

public class Bar : Foo
{
    static Bar()
    {
        print("2");
    }

    static void DoSomething()
    {
        /*...*/
    }
}

假设这是我第一次访问Bar类,在调用Bar.DoSomething()后,我期望事件的顺序是:

  1. Foo的静态构造函数(同样假设为首次访问)》打印4
  2. Bar的静态构造函数》打印2
  3. 执行DoSomething

总之,我希望输出42
经过测试,看起来只有2被输出。
那甚至不是一个答案

你能解释一下这种行为吗?


2个回答

12
规范说明:
一个类的静态构造函数在给定应用程序域中最多执行一次。静态构造函数的执行是由以下事件中的第一个触发的:
1. 创建该类的实例。 2. 引用该类的任何静态成员。
因为您没有引用基类的任何成员,所以构造函数没有被执行。
请尝试这个:
public abstract class Foo
{
    static Foo()
    {
        Console.Write("4");
    }

    protected internal static void Baz()
    {
        // I don't do anything but am called in inherited classes' 
        // constructors to call the Foo constructor
    }
}

public class Bar : Foo
{
    static Bar()
    {
        Foo.Baz();
        Console.Write("2");
    }

    public static void DoSomething()
    {
        /*...*/
    }
}

更多信息:

2
基类的默认构造函数会自动调用。如果我设计这门语言,我会认为调用构造函数就相当于创建一个类的实例。这不是构造函数的作用吗? - symbiont

6
基类静态构造函数之所以不会被调用,是因为我们还没有访问基类的任何静态成员或创建派生类的实例。
根据文档,这些情况下将调用静态构造函数:
它会在创建第一个实例或引用任何静态成员之前自动调用。
在下面的代码中,当我们调用DoSomething时,将调用基类构造函数。
public abstract class Foo
{
    static Foo()
    {
        Console.Write("4");
        j = 5;
    }

    protected static int j;

    public static void DoNothing()
    {

    }
}

public class Bar : Foo
{
    static Bar()
    {
        Console.Write("2");
    }

    public static void DoSomething()
    {
        Console.Write(j);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接