Inherit from struct

32,478

Solution 1

A struct Is Implicitly Sealed

According to this link:

Every struct in C#, whether it is user-defined or defined in the .NET Framework, is sealed–meaning that you can’t inherit from it. A struct is sealed because it is a value type and all value types are sealed.

A struct can implement an interface, so it’s possible to see another type name following a colon, after the name of the struct.

In the example below, we get a compile-time error when we try to define a new struct that inherits from the one defined above.

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

Solution 2

Struct does not support inheritance, if you need you have to use class, see 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.

Solution 3

Value types in .NET are weird in that they defined though they are classes derived from a special class called ValueType. For every value type there is a heap object type which behaves like a class object that derives from ValueType, but a value-type storage location holds a collection of bytes which either represents a primitive value, or the concatenation of the bytes necessary to hold all of its public and private fields.

Since value type storage locations just hold the bytes necessary to represent their values, and hold neither type information nor any reference to an object which would hold type information, the code which uses a value type storage location must know exactly what it is.

Conventional inheritance requires that objects hold information about their own type, but there is no provision via which value types could do so.

It would be conceptually possible (and useful) for .NET to allow some limited forms of value-type inheritance with some special rules, such that while a BaseStructure variable could only hold a BaseStructure and couldn't hold a DerivedStructure. One could define a StructureUser<T> where T:BaseStructure, and such class or method could accept any derivative of BaseStructure and use those members--including fields--which were common to the base type.

Unfortunately, it would be difficult to define rules for generics in such a way as to behave consistently in permitted scenarios and yet not break any existing code.

For example, within a class Foo<T,U> where T:U it's always possible to store a T to a variable of type U, even if U is a value type (i.e. because value types are sealed, T and U are guaranteed to be the same type). If U could be an inheritable value type and T could be a derivative, such a guarantee would not hold.

Given the difficulties associated with such inheritance, a more useful alternative would be to provide a safe (even if limited) means via which a property could expose a byref or a const-byref (a byref is the thing which is passed when a parameter uses a ref qualifier).

Such a feature would remove the unavoidable semantic distinction between fields and properties, and depending upon how it was implemented could offer some major advantages even when used with classes (e.g. it could allow for efficient mixing of immutable and mutable types).

Solution 4

Inheritance isn't alloweded between structs but structs can implement interfaces.

Solution 5

There are actually a few good reasons:

  1. Structs have no 'Type'

    ...unless they are 'boxed' into an object.

    An object on the other hand has two "header" fields in the normal CLR where the type is stored (and some GC- and locking info). Adding that would change the size of the structs, and make their size unpredictable (because some runtimes might chose to add that information differently, for example the mono runtime adds more "header" information to its objects than the .net framework runtime, or at least did so in the past)

    This boxing is actually what happens when you try to assign a struct to an interface field it implements. So it would be possible in theory, but then all your structs would be boxed, and that'd be really bad for performance reasons.

  2. Typing and fixed size

    To show why specifically inheriting structs would be a huge problem lets make a simple example.

    Consider two structs: struct MyBaseStruct { public int A; } and a hypothetical struct MyDerivedStruct : MyBaseStruct { public int B; }.

    Now what would happen when I call var array = new MyBaseStruct[10]; ?? How much size would the runtime allocate for that?

    The assignment array[0] = new MyDerivedStruct(); would be troublesome, on 32bit systems it would probably write to the first AND the second slot as well.

    Even if you'd try to "collect" all derived types it wouldn't work, what if you load another dll that defines yet another struct that derives from your base-struct?

I personally find it pretty important to know the actual issues that probably led the designers to the decision in the first place. But of course a one could also just say "because the designers of the language made it so!" or "because that's what the C# language specification says" :P

Share:
32,478

Related videos on Youtube

user2110292
Author by

user2110292

Updated on June 07, 2020

Comments

  • user2110292
    user2110292 almost 4 years

    I am try to figure out what is the problem whit my code. I have this code:

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

    And i get this error:

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

    I don't understand why? the .net not implemnet struct like class?

    • Freeman
      Freeman about 11 years
      structs and classes are different, there is no struct type class, its either one or the other.
    • bash.d
      bash.d about 11 years
      There must be something else... Is that all of your code?
    • mBardos
      mBardos about 3 years
      @Freeman the OP might come from C++ world, where structs are just a bit different classes
  • ryanwebjackson
    ryanwebjackson over 2 years
    This is some interesting food for thought.
  • Siavash Mortazavi
    Siavash Mortazavi over 2 years
    I think this is worth mentioning: .NET has an 'Implicit Inheritance' mechanism and a struct can 'implicitly' and 'internally' inherit from Object or ValueType classes (it's weird, isn't it?) This internal mechanism is not exposed, of course, and you cannot 'explicitly' have a struct inheriting from a class. Ref: docs.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorial‌​s/…