2015-04-07 18 views
6

przykład:Dlaczego otrzymuję "cykl w układzie struct" z typów fantomowych w C#?

struct Id<T> { 
    int id; 
} 

struct Thing { 
    public Id<Thing> id; 
} 

powoduje to cykliczny układ struct, ale nie widzę cykl. jeśli ID miałby pole typu T, sizeof byłby niezdefiniowany, ale tak nie jest.

czy to błąd monobloku, czy część specyfikacji?

+0

Kompiluje się dobrze w kompilatorze MS, więc jeśli nie jest niezdefiniowany w specyfikacji, jedna z dwóch implementacji jest błędna. – Servy

+1

Nie ma rzeczywistego wystąpienia 'Thing' w' Id ', więc nie ma cyklu. –

+0

@MatthewWatson Prawidłowo, więc pytanie, dlaczego nie jest skompilowany z powodu, który faktycznie nie ma zastosowania. OP twierdzi, że powinien się skompilować i uruchomić, ale mono jest błąd podczas kompilacji. – Servy

Odpowiedz

1

Jak wspomniano w komentarzach, podczas gdy ten kod kompiluje przy użyciu kompilatora MS C#, to w rzeczywistości nie jest wykonywany - daje on w środowisku wykonawczym TypeLoadException. Zauważ, że problem występuje tylko wtedy, gdy są następujące: , i . Pytanie brzmi, czy jest to problem kompilatora C# czy środowiska wykonawczego?

Ponieważ środowisko wykonawcze jest również objęte własną specyfikacją, przejrzałem wszystkie elementy specyfikacji CLI, które były nawet bardzo trafne i nie znalazłem niczego, co by to zabraniało. Nie w definicji IL (oczywiście, ponieważ IL jest uważany za poprawny), a nie w strukturach metadanych środowiska wykonawczego.

Biorąc pod uwagę to, jestem bardziej za powołaniem błędnego wdrożenia środowiska wykonawczego. Podejrzewam, że kiedy zespół Mono stanął w obliczu tego problemu, rozważali dodanie błędu kompilatora, ponieważ ta sytuacja jest mniejszym złem. A może po prostu nieprawidłowo oceniają cykliczne ograniczenie struct :)

Możliwe, że nawet nie wystąpił awaria podczas uruchamiania, dzięki czemu kompilator C# stał się jeszcze bardziej odpowiedni. Nie mam sposobu na sprawdzenie tego, oczywiście :)

Niestety, oznacza to, że nie możesz użyć tej przydatnej konstrukcji. Albo upewnij się, że jeden z typów jest class, albo po prostu musisz zrobić inny typ dla każdego z tych IdOfSomething swoich. Po prostu ciesz się, że kompilator Mono C# powiedział ci tak, zanim dowiedziałeś się w czasie wykonywania: P