Почему статический конструктор родительского класса не вызывается при вызове метода во вложенном классе? - PullRequest
5 голосов
/ 13 апреля 2010

Учитывая следующий код, почему статический конструктор "Outer" не вызывается после первой строки "Main"?

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

Ответы [ 4 ]

6 голосов
/ 13 апреля 2010

Ответ на ваш вопрос приведен в разделе 10.12 спецификации, в котором говорится:

Выполнение статического конструктора инициируется первым из следующих событий, происходящих в домене приложения:

• Создан экземпляр типа класса.

• Ссылка на любой из статических членов типа класса.

Поскольку вы не сделали ни одну из этих двух вещей, ctor не выполняется.

5 голосов
/ 13 апреля 2010

В случае вложенных классов, если вложенный класс никогда не ссылается на статические члены своей внешней области видимости, компилятору (и CLR) не требуется вызывать статический конструктор этого внешнего класса.

Если вы хотите принудительно запустить статический конструктор, просто добавьте код к внутреннему типу, который выполняет чтение поля или свойства внешнего типа.

Вы можете узнать больше о ленивой семантике инициализации C # на Блог Джона Скита - это довольно хорошо. Вы также можете проверить его книгу - C # In Depth , она также охватывает эти темы ... подробно.

3 голосов
/ 13 апреля 2010

Outer.Inner просто ссылается на тип, на самом деле он ничего не вызывает в "Outer".

0 голосов
/ 13 апреля 2010

Статический инициализатор выполняется только тогда, когда содержащий класс используется впервые.

Вызывая Outer.Inner, вы вообще не используете Outer, поскольку Outer.Inner отличается от Outer. Таким образом, статический инициализатор в Outer не будет работать.

...