Страницы

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

среда, 1 января 2020 г.

Вызвать static конструктор без обращений к классу

#c_sharp #static


Возможно ли, какими нибудь окольными путями (меняя код в рамках одного класса Test),
заставить программу на старте вызывать статик конструктор класса Test?

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

using System;

namespace Program {

    public static class Test {
        static Test() {
            Console.WriteLine("Hello World!");   
        }
    }

    public class Activator {

        public static void Main(string[] args) {
            Console.WriteLine("start...");
        }

    }

}


Поясню, я хочу увидеть в консоли:


  Hello World!
  
  start...

    


Ответы

Ответ 1



Без дополнительного вызова (хотя бы одного), который запустит инициализацию твоих типов - нет, нельзя. С ним можно. using System; using System.Reflection; using System.Runtime.CompilerServices; namespace Program { [InvokeStaticCtorAttribute] public static class Test { static Test() { Console.WriteLine("Hello World!"); } } public class Activator { public static void Main(string[] args) { InvokeStaticCtorAttribute.InitializeStaticCtors(); Console.WriteLine("start..."); } } [AttributeUsage(AttributeTargets.Class)] public class InvokeStaticCtorAttribute : Attribute { public static void InitializeStaticCtors() { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { if (type.GetCustomAttribute() != null) RuntimeHelpers.RunClassConstructor(type.TypeHandle); } } } } }

Ответ 2



Для комментария слишком много, для ответа... в общем пусть пока повисит, там видно будет. Для приведенного примера статического конструктора мало что можно сделать, так или иначе класс упомянуть в коде придется. Если же нужен доступ к статическим константам, как, например, в классе Math, или значениям из файлов конфигурации, то можно довольно легко выйти из положения, вспомнив о том, что свойства, на самом деле, являются одним или парой методов. Таким образом, для констант или значений из конфигурации, которые нужно получить без явного вызова методов инициализации, достаточно заменить поля на свойства (readonly для констант). Обращение к статическому свойству равноценно вызову статического метода, а значит с тем же успехом заставит CLR загрузить класс и вызвать статический конструктор.

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

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