typy Wartość w .NET są dziwne w tym, że choć są one zdefiniowane klasy pochodzące ze specjalnej klasy o nazwie ValueType
, a dla każdego typu wartości jest typ obiektu sterty, który zachowuje się jak obiekt klasy pochodnej ValueType
, ale lokalizacja przechowywania typu wartości przechowuje kolekcję bajtów, która reprezentuje prymitywną wartość lub konkatenację bajtów niezbędnych do przechowywania wszystkich jej publicznych i prywatnych pól. Ponieważ lokalizacje typu wartości przechowują tylko bajty niezbędne do reprezentowania ich wartości i nie przechowują ani informacji o typie, ani żadnych odniesień do obiektu, który przechowywałby informacje o typie, kod, który wykorzystuje lokalizację przechowywania typu wartości, musi dokładnie wiedzieć, co to jest. Konwencjonalne dziedziczenie wymaga, aby obiekty zawierały informacje na temat ich własnego typu, ale nie ma przepisu, za pomocą którego mogłyby to robić typy wartości.
Byłoby koncepcyjnie możliwe (i przydatne) dla .NET, aby umożliwić pewne ograniczone formy wartość typu dziedziczenia z pewnych szczególnych zasad, tak że gdy zmienna BaseStructure
mógł tylko trzymać BaseStructure
i nie mógł posiadać DerivedStructure
, można zdefiniować StructureUser<T> where T:BaseStructure
, a taka klasa lub metoda może zaakceptować każdą pochodną BaseStructure
i użyć tych elementów - w tym pól - wspólnych dla typu podstawowego.Niestety, trudno byłoby zdefiniować reguły dla generycznych w taki sposób, aby zachowywać się konsekwentnie w dozwolonych scenariuszach, a jednocześnie nie łamać istniejącego kodu. Na przykład w klasie Foo<T,U> where T:U
to zawsze można przechowywać T
do zmiennej typu U
, nawet jeśli U
jest typ wartości (w tym scenariuszu, ponieważ typy wartości są uszczelnione, T
i U
są gwarancją samo rodzaj). Jeśli U
może być dziedzicznym typem wartości, a T
może być pochodną, taka gwarancja nie byłaby zachowana. Biorąc pod uwagę trudności związane z takim dziedziczeniem, bardziej użyteczną alternatywą byłoby zapewnienie bezpiecznych (nawet jeśli ograniczonych) środków, za pomocą których właściwość mogłaby narazić byref lub const-byref (byref jest rzeczą, która jest przekazywana, gdy parametr wykorzystuje kwalifikator ref
). Taka funkcja usunęłaby nieuniknione semantyczne rozróżnienie między polami i właściwościami, a w zależności od tego, w jaki sposób została zaimplementowana, może przynieść pewne istotne korzyści, nawet jeśli jest używana z klasami (na przykład może umożliwić wydajne mieszanie typów niezmiennych i zmiennych).
Struktury i klasy są różne, nie ma klasy typu struct, ani jednej, ani drugiej. – Freeman
Musi być coś jeszcze ... Czy to cały twój kod? –