1

I am confused about inheritance in .NET and here is why.

I was previously of the understanding that a structure cannot inherit from a class in .NET, so for example, the following won't compile:

struct MyStruct : MyClass
{

}

But today I read that integers (and other value types) are structs and not objects and they inherit from the ValueType class. The ValueType class inherits from System.Object and its purpose is to override certain methods in System.Object to make these methods suitable for Value Types.

So what's the deal? Can a structure inherit from a class in .NET, can it not or can it only in certain circumstances?

Thanks

JMK
  • 27,273
  • 52
  • 163
  • 280
  • 2
    Duplicate? http://stackoverflow.com/questions/10727151/if-a-struct-cannot-inherit-another-class-or-struct-why-does-int32-have-a-tostri – Jake1164 Jun 10 '12 at 18:04
  • @Jake1164 Yes actually, this guy is basically asking the same question I am! My mistake! – JMK Jun 10 '12 at 18:08

1 Answers1

3

Within the guts of .net, the definition for a struct containing certain members is the same as a definition for a class which those same fields and members, and which inherits from System.ValueType. Note that compilers will not allow one to declare a class which inherits ValueType, but when one declares a struct, the compiler, "behind the scenes" declares a class which does.

What makes value types special in .net is the way the run-time allocates storage locations (variables, fields, parameters, etc.) When a storage location of a type not inheriting from ValueType is declared, the runtime will allocate space for a heap object reference. By contrast, when a storage location of a type inheriting from ValueType is declared, the runtime will allocate space for all the public and private fields of that type. For a type like int, the system allocates a private field which is of a special primitive type, outside the normal type system.

Note that a storage location of a value type doesn't really hold an instance of that type; instead is an instance of that type, and holds all of the fields of that type. A statement like struct1 = struct2 does not replace the value-type instance struct1 with the instance struct2. Instead, it copies all of the fields from struct2 over the corresponding fields in struct1. Likewise if a value-type storage location is passed as a method to a procedure without using the ref keyword, what is passed is not the struct instance itself, but rather the contents of its fields.

If it is necessary to copy a value-type storage location to a one of type not derived from ValueType (e.g. Object or IComparable), the system will create a new heap-object instance of the value type, copy all the fields from the value type to that new instancen and store a reference to that new instance in the target storage location. This process is called "boxing". Most compilers will do this implicitly, thus attempting to behave as though a value type storage location holds an object which derives from ValueType. It's important to note, though, that this is an illusion. If type X derives from Y, one has an X named xx and a Y named yy, and one performs xx = yy, such a statement should cause xx and yy to refer to the same object instance. That will happen if xx and yy are types not derived from ValueType, even if yy holds an instance of something derived from ValueType. It will not happen, however, if xx and/or yy derives from ValueType. In that case, the system will copy fields from one instance to another (possibly new) instance.

supercat
  • 77,689
  • 9
  • 166
  • 211