【问题标题】:Why isn't the static constructor of the parent class called when invoking a method on a nested class?为什么调用嵌套类的方法时不调用父类的静态构造函数?
【发布时间】:2011-02-07 10:48:40
【问题描述】:

给定以下代码,为什么在“Main”的第一行之后没有调用“Outer”的静态构造函数?

namespace StaticTester
{
    class Program
    {
        static void Main( string[] args )
        {
            Outer.Inner.Go();
            Console.WriteLine();

            Outer.Go();

            Console.ReadLine();
        }
    }

    public static partial class Outer
    {
        static Outer()
        {
            Console.Write( "In Outer's static constructor\n" );
        }

        public static void Go()
        {
            Console.Write( "Outer Go\n" );
        }

        public static class Inner
        {
            static Inner()
            {
                Console.Write( "In Inner's static constructor\n" );
            }

            public static void Go()
            {
                Console.Write( "Inner Go\n" );
            }
        }
    }
}

【问题讨论】:

    标签: c# static-constructor


    【解决方案1】:

    规范第 10.12 节回答了您的问题,其中规定:

    静态构造函数的执行 由第一个触发 以下事件发生在一个 应用领域:

    • 一个实例 类类型被创建。

    • 任何一个 类类型的静态成员 被引用了。

    由于你没有做这两件事,所以没有执行ctor。

    【讨论】:

    • 但是Inner 不是Outer 的成员吗?并且引用了Inner。当然Inner 不是实例成员?那么它不是静态成员吗​​?也许嵌套类在这方面不被视为成员?
    • @JeppeStigNielsen:你说得很好;我说得不准确。我应该说任何静态字段、方法、属性、事件、索引器或运算符
    • 您准确地引用了规范。所以你真的是说规范不精确(或者你说你写了规范的这一部分)?或者在这种情况下,嵌套类型可能不被视为成员。
    • @JeppeStigNielsen:规范可能会被改写以使其更加清晰。我会向 Mads 提及的。
    【解决方案2】:

    在嵌套类的情况下,如果嵌套类从不引用其外部范围的静态成员,则编译器(和 CLR)不需要调用该外部类的静态构造函数。

    如果您想强制静态构造函数运行,只需将代码添加到执行外部类型的字段或属性读取的内部类型。

    您可以在Jon Skeet's blog 上阅读更多关于 C# 的惰性初始化语义的信息 - 这非常好。你也可以看看他的书 - C# In Depth,它也涵盖了这些主题......深入。

    【讨论】:

    • 这很有趣,我拿出了我的 C# In Depth 副本来帮助找出原因。
    【解决方案3】:

    Outer.Inner 只是指一种类型,它实际上并没有在“Outer”上调用任何东西。

    【讨论】:

    • 我把这个放在这里,所以其他人不要像我一样思考这个问题。
    【解决方案4】:

    只有在第一次使用包含类时才会执行静态初始化程序。

    通过调用Outer.Inner,您根本没有使用Outer,因为Outer.InnerOuter 是不同的类型。因此,Outer 中的静态初始化程序将不会运行。

    【讨论】:

    • 啊,没有看到你的评论:)
    猜你喜欢
    • 2015-11-28
    • 2012-08-30
    • 2015-04-24
    • 2011-03-24
    • 2015-12-08
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    相关资源
    最近更新 更多