Value Types

Bill Venners: C# and the CLR support value types, which can exist both as values on
the stack and objects on the heap. By contrast, Java has separate primitive types and wrapper
types. In the design of C# and the CLR, to what extent were value types a performance consideration
versus a usability consideration?

Anders Hejlsberg: There is clearly a performance aspect to it. One possible solution would
be to say, "There are no value types. All types are heap allocated. Now we have representational
identity, and so we're done, right?" Except it performs like crap. We know that from
Smalltalk systems that did it that way, so something better is needed.

Over time, we've seen two schools of thought. Either you are very object-oriented, pay the
performance penalty, and get those capabilities; or you bifurcate a type system, like Java and
C++. In a bifurcated type system, you have primitives, which are endowed with special capabilities, and the user-
extensible realm of classes, in which you don't get to do certain things. And there's no über-type
for everything.
The notion that you can treat any piece of data as an object seems so benign. What's the big
deal?
When you can't treat ints as primitives, you can just use a wrapper type
that has an identity. That's true, but all that manual wrapping is irritating and gets in your
way.

The way we implemented it in C# and the CLR, I think we get to have our cake and eat it too.
Value types are just as efficient as Java or C++ primitives, as long as you treat them as values.
Only if you try to treat them as objects do they become heap
allocated objects on demand, through boxing and unboxing.
It gives you this beauty and simplicity.