Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Inherit a struct in C#? Why (can)not?

0.00/5 (No votes)
18 Feb 2015 1  
Understanding structs - why C# does not allow a struct to be inherited

Introduction - Why Use Structs Anyway?

Why struct anyway?
We all like C#'s structs very much [an idea alien to Java, apart from primitive types]. Structs, when they do not have to be boxed frequently, provide a nice way to handle relatively small and short lived data.

Allocations and deallocations of value types are in general cheaper than allocations and deallocations of reference types, since structs are allocated either on the stack or inline in containing types and deallocated when the stack unwinds or when their containing type gets deallocated, while reference types are allocated on the heap and garbage-collected.

Hmmm, It Won't Let Me Inherit....

Object Oriented Programming gives us the ability to do quite a lot of stuff, and the basic concept in OO is of course the inheritance.

Many of us have tried at one point to inherit a struct, only to find out that C# does not allow it.

Consider this code for example:

// What on earth can be wrong with this simple code? 
// NOTE: DateTime is a struct, if you didn't already know it, Now() is a good time to find out :)
struct MyDateTime : DateTime
{
    double SecondsFromMyBirthday { get; private set; }
}

// or with this fairly reasonable inherit request:
struct Point
{
   int x, y;
}

struct Point3D : Point
{
   int z;
}

An honest programmer wishes to expand the DateTime struct, why shouldn't she?

This code will produce the compile time error: Type 'DateTime' in interface list is not an interface (the reason for this specific error message is the fact that since inheritance is not allowed the compiler expects only an interface after the colon symbol - it does not even take a misuse of inheritance into account...)

If the struct would be replaced to class, the compile time error will produce: 'MyDateTime': cannot derive from sealed type 'System.DateTime'

We understand then, that System.DateTime is (implicitly) sealed. But why?

Note: Actually the fact is that all struct types implicitly inherit from the class System.ValueType, which, in turn, inherits from class object.

Note: Although a Struct cannot be inherited, it can implement an interface.

The Answer

A struct has a fixed size allocated already on the stack.

Now consider the Point / Point3D example above which seems like a nice innocent case. Consider the following line of code:

// Assume we have a p2d which is a Point, 
// and a p3d which is a Point3D
p2d = p3d; 

What should happen on the assignment line then? A memory expansion of p2d on the stack to support the assignment?

Furthermore - structs, being a value type of course, do not use references (unless boxed), this would make polymorphism somewhat meaningless since there is no indirection via a reference pointer.

Also, consider the case of arrays - arrays of value types are stored "inline" (for performance and garbage collection reasons). If we use a struct without knowing it is actually a "derived struct", it will cause memory corruption.

In conclusion - we've seen why it is highly unreasonable for .NET to allow inheritance of a struct. The good news is that you can always inherit ... well ... a class!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here