2013-03-14 6 views
11

Próbuję dowiedzieć się, jaki jest problem z odrobiną mojego kodu. mam ten kod:Dziedzicz z struct

public struct MyStructA 
{ 
    public MyStructA(string str) 
    { 
     myString= str; 
    } 

    public string myString; 
} 

public struct MyStructB: MyStructA 
{ 
    public string myReversString; 
} 

i dostaję ten błąd:

Error at compile time: Type 'MyStructA' in interface list is not an interface 

ja nie rozumiem, dlaczego? .net nie implemnet struct like class?

+0

Struktury i klasy są różne, nie ma klasy typu struct, ani jednej, ani drugiej. – Freeman

+0

Musi być coś jeszcze ... Czy to cały twój kod? –

Odpowiedz

16

struct jest niejawnie Sealed

Według tego link:

Każdy struct w języku C#, niezależnie od tego, czy jest zdefiniowany przez użytkownika, czy zdefiniowany w .NET Framework, jest zapieczętowany - co oznacza, że ​​nie można go dziedziczyć. Struktura jest plombowana, ponieważ jest to typ wartości i wszystkie typy wartości są zapieczętowane.

Struktura może implementować interfejs, więc po nazwie struktury można zobaczyć inną nazwę typu po dwukropku.

W poniższym przykładzie otrzymujemy błąd podczas kompilacji, gdy próbujemy zdefiniować nową strukturę, która dziedziczy po definicji zdefiniowanej powyżej.

public struct PersonName 
{ 
    public PersonName(string first, string last) 
    { 
     First = first; 
     Last = last; 
    } 

    public string First; 
    public string Last; 
} 

// Error at compile time: Type 'PersonName' in interface list is not an interface 
public struct AngryPersonName : PersonName 
{ 
    public string AngryNickname; 
} 
3

Struct nie obsługuje dziedziczenia, jeśli trzeba trzeba użyć klasy, patrz msdn

There is no inheritance for structs as there is for classes. A struct cannot inherit from another struct or class, and it cannot be the base of a class. Structs, however, inherit from the base class Object. A struct can implement interfaces, and it does that exactly as classes do.

+1

doskonała odpowiedź; tanx –

1

Dziedziczenie nie jest dozwolone między strukturami, ale struktura może implementować interfejsy.

1

Od MSDN;

There is no inheritance for structs as there is for classes. A struct cannot inherit from another struct or class, and it cannot be the base of a class. Structs, however, inherit from the base class Object. A struct can implement interfaces, and it does that exactly as classes do.

jednak pamiętać, ponieważ kodowanym są rodzajem wartość i oni posiądą System.ValueType

1

elemencie może implementować interfejs, ale nie mogą dziedziczyć z innej struktury. Z tego powodu członkowie klasy nie mogą być deklarowani jako chronieni.

2

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).