Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Статический конструктор структуры C#

#c_sharp #структуры #конструктор


Существует ли различие между статическими конструкторами структур и классов и их
вызовами в C#?
    


Ответы

Ответ 1



Есть довольно известное заблуждение, будто статические конструкторы не работают для структур. Но это не так. просто они срабатывают несколько иначе, нежели для классов. Разница например вот в чем: у ссылочных типов (классов в том числе) статический конструктор вызывается перед первым созданием экземпляра класса. У структур он вызывается при обращении к статическим членам структуры. Пример: struct Foo { static Foo() { Console.WriteLine("from static Foo"); } public static int Bar = 10; } class FooClass { static FooClass() { Console.WriteLine("from static FooClass"); } public static int Bar = 10; } // перед созданием экземпляра вызовется статический конструктор, //который напечатает текст "from static FooClass" var fooCl = new FooClass(); // а здесь статический конструктор вызван не будет var foo = new Foo(); // // он будет вызван здесь, если раскомментировать следующую строку //Foo.Bar = 11; А теперь небольшое объяснение этому колдунству. Дело в том, что типы-значения в C# (и структуры в том числе) имеют массу отличий от ссылочных типов (в том числе классов). Одним из таких отличий является работа конструктора по умолчанию. Для структур в целях сохранения быстродействия (если не ошибаюсь) при вызове конструктора по умолчанию выполняется инициализация всех полей значениями по умолчанию. Соответственно, создания экземпляра как такового не происходит, тогда как статический конструктор вызывается при первом инстанцировании экземпляра. Но если добавить структуре какой-либо конструктор с аргументами (добавить свой конструктор по умолчанию не получится) и создать экземпляр структуры через этот конструктор, то вызов статического конструктора произойдёт. Пример: struct Foo { static Foo() { Console.WriteLine("from static Foo"); } public Foo(int i) { } } // здесь произойдёт вызов статического конструктора, // так как происходит "обычное" создание экземпляра var foo = new Foo(1);

Комментариев нет:

Отправить комментарий