2010-04-13 15 views
5

Dato il seguente codice, perché il costruttore statico di "Outer" non è chiamato dopo la prima riga di "Main"?Perché il costruttore statico della classe genitore non viene chiamato quando si richiama un metodo su una classe nidificata?

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

risposta

5

Nel caso di classi nidificate, se la classe nidificata non fa mai riferimento ai membri statici del suo ambito esterno, il compilatore (e CLR) non sono obbligati a chiamare il costruttore statico di quella classe esterna.

Se si desidera forzare l'esecuzione del costruttore statico, è sufficiente aggiungere codice al tipo interno che esegue una lettura di un campo o di una proprietà del tipo esterno.

È possibile leggere ulteriori informazioni sulla semantica di inizializzazione pigra di C# su Jon Skeet's blog - è abbastanza buona. Puoi anche dare un'occhiata al suo libro - C# In Depth, copre anche questi argomenti ... in profondità.

+0

Questo è divertente, ho tirato fuori la mia copia di C# in profondità per aiutare a capire perché. –

3

Outer.Inner si riferisce solo a un tipo, in realtà non sta invocando nulla su "Outer".

+0

Ho messo questo qui così altri non meditare questo per tutto il tempo che ho fatto. –

0

Un inizializzatore statico viene eseguito solo quando la classe contenente viene utilizzata per la prima volta.

Chiamando Outer.Inner, non si utilizza Outer a tutti, dal momento che Outer.Inner è un tipo diverso rispetto Outer. Pertanto, l'inizializzatore statico in Outer non verrà eseguito.

+0

Ah, non ho visto il tuo commento lì :) –

6

La tua domanda si risponde con la sezione 10.12 della specifica, in cui si afferma:

L'esecuzione di un costruttore statico è innescato dal primo dei seguenti eventi che si verificano all'interno di un dominio applicazione:

• Un'istanza di viene creato il tipo di classe.

• Qualsiasi i membri statici del tipo di classe sono referenziati.

Dato che non hai fatto nessuna di queste due cose, il ctor non viene eseguito.

+0

Ma 'Inner 'non è un membro di' Outer'? E 'Inner' è referenziato. Sicuramente 'Inner' non è un membr di istanza? Quindi non è un membro statico? Forse le classi annidate non devono essere considerate membri a questo riguardo? –

+0

@JeppeStigNielsen: fai un buon punto; Ero impreciso Avrei dovuto dire qualsiasi dei campi, metodi, proprietà, eventi, indicizzatori o operatori * statici *. –

+0

Hai citato la specifica con precisione. Quindi stai dicendo che le specifiche sono imprecise (o forse stai dicendo che hai scritto questa parte della specifica)? O forse i tipi annidati non devono essere considerati membri in questo contesto. –

Problemi correlati