2015-04-07 2 views
6

esempio:perché ottengo un "ciclo nel layout della struttura" con tipi di fantasma in C#?

struct Id<T> { 
    int id; 
} 

struct Thing { 
    public Id<Thing> id; 
} 

questo provoca un layout struct ciclica, ma non vede il ciclo. se Id aveva un campo di tipo T, sizeof sarebbe indefinito, ma non lo è.

è presente un bug mono o parte della specifica?

+0

compila bene nel compilatore MS, in modo meno che non sia indefinito nelle specifiche, una delle due implementazioni è sbagliato. – Servy

+1

Non esiste un'istanza reale di "Cosa" in "Id ", quindi non esiste un ciclo. –

+0

@MatthewWatson Corretto, quindi la domanda è perché non riesce a compilare con un motivo che non si applica effettivamente. L'OP sta affermando che dovrebbe compilare ed eseguire, ma mono sta commettendo errori durante la compilazione. – Servy

risposta

1

Come discusso nei commenti, mentre questo codice viene compilato utilizzando il compilatore MS C#, in realtà non esegue, fornisce un TypeLoadException in fase di esecuzione. Si noti che il problema solo appare quando sia i tipi sono struct. Quindi la domanda è, questo è un problema del compilatore C# o del runtime?

Poiché il runtime è anche coperto dalle sue specifiche, ho esaminato tutti i pezzi delle specifiche CLI che erano persino vagamente rilevanti, e non ho trovato nulla che potesse vietarlo. Non nella definizione di IL (ovviamente, poiché l'IL è considerato valido), e non nelle strutture di metadati di runtime.

Detto questo, io sono più a favore di chiamare l'implementazione runtime viziata. Sospetto che quando il team Mono si è trovato di fronte a questo problema, hanno preso in considerazione l'aggiunta di un errore del compilatore perché questa situazione era il male minore. O forse valutano solo il vincolo ciclico struct in modo errato :)

Potrebbe anche essere possibile che non abbia utilizzato il crash in runtime, rendendo il compilatore C# ancora più corretto. Non ho modo di verificare questo, naturalmente :)

Purtroppo, questo significa che non è possibile utilizzare che a portata di mano costrutto del tuo. O assicurati che uno dei tipi sia un class o dovrai semplicemente creare un tipo diverso per ciascuno di questi IdOfSomething tuo. Basta essere contento che il # compilatore Mono C te l'ha detto prima di trovare in fase di esecuzione: P