Why does System.Int32 that derives from System.Object (thru System.ValueType) a value type while System.Object is a reference type?
Because System.ValueType
is what allows us to use boxing/unboxing by overriding certain virtual members from System.Object.
http://msdn.microsoft.com/en-us/library/system.valuetype.aspx explains it pretty well:
Data types are separated into value types and reference types. Value types are either stack-allocated or allocated inline in a structure. Reference types are heap-allocated. Both reference and value types are derived from the ultimate base class Object.
In cases where it is necessary for a value type to behave like an object, a wrapper that makes the value type look like a reference object is allocated on the heap, and the value type's value is copied into it. The wrapper is marked so the system knows that it contains a value type. This process is known as boxing, and the reverse process is known as unboxing. Boxing and unboxing allow any type to be treated as an object.