5

I know that my question seems dumb but I am confused. I appreciate if someone clarify this for me.

I know that structs, e.g. Int32, are value types and are instantiated on stack while classes are reference types and are instantiated on heap. I also know that all the structs are derived from System.Object type, which is a class. I wonder how this is possible that the supertype, System.Object, is a reference type and the subtype, Int32, is a value type? Where should I look to understand how this works?

Morteza
  • 341
  • 5
  • 13
  • 7
    Related reading: [The Stack Is An Implementation Detail](http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx) – Heinzi Mar 23 '12 at 07:29
  • 2
    Possible duplicate of http://stackoverflow.com/questions/1682231/how-do-valuetypes-derive-from-object-referencetype-and-still-be-valuetypes – daryal Mar 23 '12 at 07:37
  • 1
    http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx – Mike Zboray Mar 23 '12 at 08:04

2 Answers2

12

I know that structs, e.g. Int32, are value types and are instantiated on stack while classes are reference types and are instantiated on heap.

You do not know that, because in order to be classified as knowledge a belief must be true. That belief is certainly not true, though many people believe it.

Value types are sometimes allocated on the stack. References are sometimes allocated on the stack and refer to memory allocated on the heap. Value types are sometimes allocated on the heap. (And of course value types and references may also be allocated in registers which are neither stack nor heap.)

What determines what storage is allocated on the heap and what is allocated on the stack is the known lifetime requirements of the storage, not what kind of thing it is. If a variable is known to be short-lived then it can be allocated on the stack; if it is not known to be short-lived then it must be allocated on the heap.

I also know that all the structs are derived from System.Object type, which is a class. I wonder how this is possible that the supertype, System.Object, is a reference type and the subtype, Int32, is a value type?

I suspect that you don't understand what "inherits from" means in the first place if this is confusing to you. When we say that System.Int32, a value type, inherits from System.Object, a reference type, we mean that all members of Object are also members of Int32. Object has a method "ToString". That's a member of Object. Therefore Int32 also has a method "ToString", because Int32 inherits from Object.

That is all that inheritance means. I suspect that you believe that inheritance means something else, and that whatever that "something" is precludes value types from extending reference types. Whatever belief you have that makes you think that value types cannot inherit from reference types is clearly false, since obviously they do.

I am interested to learn what false things people believe about programming languages; what is it that you think incorrectly is true about the inheritance relationship that would preclude value types from deriving from reference types?

You should read and understand all of these articles:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

http://ericlippert.com/2011/09/19/inheritance-and-representation/

And extra bonus, this one might also be helpful to you:

http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 5
    I'm not the OP, but I think that a common belief in inheritance goes like this: If you create an object of type `Derived`, you must (conceptionally) create an object of type `Base` which is then "appended" with every further derived type until you have constructed `Derived` (after all, we are calling every base constructor in the chain). Therefore, to create an `Int32` you must create an `Object` and thus a reference type. – Michael Stum Mar 23 '12 at 16:37
  • Thank you Eric. I was thinking exactly like what Michael said and it was somehow strange for me. – Morteza Mar 23 '12 at 21:01
  • 3
    @MichaelStum: The key word there is "conceptually" -- indeed, a construction of an int *conceptually* is a construction first of an object. But *in practice* that's not what *actually* happens because the system has been set up carefully so that it doesn't *need* to happen. – Eric Lippert Mar 23 '12 at 22:46
3

First of all, the distinguishing feature of value types is not where they are stored but how they are passed to methods. Struct's are passed by value; that is a copy of the argument is created and passed. Any changes to the copy within the method does not affect the actual argument (unless they share the same reference) Reference types are passed by reference; that is a pointer to the actual argument is passed.

Yes, structs are derived from ValueType. And ValueType is derived from Object. So, ultimately structs are also derived from Object. (For example, the methods ToString(), ==, Equals(), GetHashCode() and perhaps a few others are defined in Object and hence also available in struct's)

However, the semantics of argument passing are not defined within classes themselves; there is no code within the definition of Object that says "any instances of my subtypes are to be passed by reference" and there is no code within the definition of ValueType that says "any instances of my subtypes are to be passed by value". [Perhaps there is a special attribute but that doesn't count] It is the responsibility of the compiler to honor that. (There is some code somewhere within C# compilers that says "generate code such that descendants of ValueType will be passed by value and others will be passed by reference")

Eric Lippert's blog is a fantastic resource on many issues about C#, and you should read the link @Heinzi gave for further clarifications.

Ali Ferhat
  • 2,511
  • 17
  • 24