2010-11-15 17 views
11

Czy istnieje sposób w języku C# lub .net IL, aby wymusić na klasie, która ma inicjator typu (konstruktor statyczny), aby się załadować, bez uzyskiwania dostępu do żadnego z jego parametrów?Wymuszanie obciążenia klasy

Zakładając Mam klasę

public static class LogInitialization { 
    static LogInitialization() { 
     System.Console.WriteLine("Initialized"); 
    } 
} 

Czy istnieje sposób, aby linia ta drukować?

Należy zauważyć, że klasa jest statyczna, więc nie mogę utworzyć instancji, aby wymusić inicjalizację, i nie ma ona żadnych publicznych członków, więc nie mogę uzyskać do nich dostępu, aby ją uruchomić.

Odpowiedz

12

Szperając w specyfikacji CLI, znalazłem odniesienie do metody RuntimeHelpers.RunClassConstructor

Jeśli język pragnie zapewnić bardziej sztywne zachowania - np typ inicjalizacji automatycznie wyzwala wykonanie z inicjalizatorów klasę bazową, w górę -to-dolny zamówienie - wtedy może to zrobić przez:

  • definiowania ukrytych statycznych pól i kod każdego konstruktora klasy, które dotyka ukryty statycznego pola swojej klasie bazowej i/lub interfejsów przy realizacji, lub
  • , wykonując jawne połączenia z System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (patrz Partycja IV).
+2

Aby tego użyć, należy podać wynik właściwości 'TypeHandle' na instancji' Type'. – Sam

7

Zazwyczaj tworzę pustą metodę Init na klasach z konstruktorami statycznymi, aby wymusić wykonanie konstruktora statycznego. to znaczy.

public static void Initialize() 
{ 
    // this will force your static constructor to execute, obviously 
} 

Mimo to, zawsze można pójść na Type.TypeInitializer z refleksji ... http://msdn.microsoft.com/en-us/library/system.type.typeinitializer.aspx

EDIT: Jeszcze jedna rzecz, którą zrobiłeś w przeszłości, jest stworzenie atrybut o nazwie RequiresInitializationAttribute następnie na AssemblyLoad przeskanuj zespół pod kątem typów z takim atrybutem i użyj type.TypeInitializer, aby wymusić wykonanie konstruktora statycznego po załadowaniu zestawu zawierającego.

Domyślam się, że prawdziwe pytanie, jak zwykle, jest ... co próbujesz osiągnąć?

+0

Tak, mógłbym po prostu wywołać sam '.cctor' - po prostu nie byłem pewien, czy to uniemożliwiłoby CLR wywoływanie go ponownie. – configurator

+0

Również wywoływanie inicjalizatora typów na typach statycznych nie działa! "Nie można utworzyć wystąpienia A, ponieważ jest to klasa abstrakcyjna." Nie rozumiem, dlaczego ta wiadomość jest powiązana, ale to właśnie dostaję. – configurator

+0

Co do tego, co próbuję osiągnąć, w zasadzie kompiluję się z języka, który ma ścisłe reguły dotyczące tego, kiedy klasy powinny być ładowane - więc chcę załadować je we właściwym czasie. – configurator