9

假设我有 2 个课程:

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

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

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

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

  1. Foo 的静态构造函数(再次假设第一次访问)> 打印4
  2. Bar 的静态构造函数 > 打印2
  3. 执行DoSomething

在底线,我希望42被打印出来。
经过测试,似乎只有2正在打印。
这甚至不是一个答案

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

4

2 回答 2

11

该规范指出:

类的静态构造函数在给定的应用程序域中最多执行一次。静态构造函数的执行由在应用程序域中发生的以下第一个事件触发:

  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()
    {
        /*...*/
    }
}

了解更多信息:

于 2013-11-20T09:52:23.377 回答
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);
    }
}
于 2013-11-20T09:46:55.320 回答