Reputation: 15817
I have a good understanding of Object Oriented programming in .NET and Java. I understand that everything in Java and .NET derives from an Object.
My question is about primitive types. I understand that primitive types do not derive from Object and I also understand how wide they are e.g. a byte is 8 bits and an integer is 32 bits. I also understand that boxing are the object equivalents.
My question is: how are primitive types actually implemented if they are not Objects? I have a little knowledge of compiler theory but perhaps need to delve more into it.
In my SCJP book it says: "if you exclude primitive types then everything in Java is an object". It also says the same in my .NET book. They do not go into the details.
I have spoken about Java in this question as I come from a Java background and Java is Object Oriented (like .net). However, I am looking for an answer that is .NET specific.
Upvotes: 0
Views: 917
Reputation: 942040
It depends on the glasses you wear. If you have "implementation" glasses then you'll see that any reference type value has an object header. Which makes them inherit System.Object. The object header has two fields, the sync-block that stores various bits of info like the hash code and the thread ID that called Monitor.Enter(). The important field is the second one, the method table pointer. Which identifies the object type. The method table contains the addresses of the methods of the class, it will always start off with Equals, GetHashCode and ToString, the methods that Object implemnts.
Wearing those same glasses, a value type value does not have this object header. It only occupies the amount of space required to store the value. One byte for a bool, two bytes for a Char, four bytes for an int, etcetera. Which makes value types very efficient.
The second pair of glasses you can put on are the "type system" glasses. A value type value can always be converted to an object. And back. This conversion is called the boxing conversion. Going back is called unboxing. Pop on the implementation glasses real quick and you'll see that you indeed get an object with those two fields, the method table pointer identifies the value type. The method table has additional method pointers. Like those for IConvertible, an interface implemented by value types. The rest of the object, beyond those two fields, is occupied by the value type value bits. The same bits it had when it was still a simple value before the boxing conversion. And the boxed object lives on the garbage collected heap, just like all reference type objects.
In the vast majority of cases, the C# or VB.NET compiler applies the boxing conversion completely automatically. You don't have to write a cast in your code yourself. You can for example call ToString or one of the IConvertible methods and you'll get the boxing conversion for free.
This creates the illusion that a value type inherits from System.Object. It is a pretty decent illusion, anybody wearing "type system" glasses will insist that a value type absolutely inherits from Object. If you wear "implementation" glasses then you tend to worry a bit about the boxing. It is heavily optimized but it certainly isn't for free. It costs cpu cycles to make the conversion and a boxed value type value takes a lot more space and creates garbage. One of the reasons that the generic collection types have completely replaced the old System.Collection classes.
Upvotes: 2
Reputation: 9507
Short answer: Primitive types derives from System.Object and it is implemented like any other type in .net.
Long answer: However, primitive types are so called in .NET because the classes that supports them are recognized by the compiler as built-in types. Also, primitive types are not reference types, they are value types (also called lightweight types in .net), therefore they are not allocated on the managed heap but on thread stack.
For example:
var a = new Int32(16);
var b = 16;
Both declarations will generate the same IL instructions. The compiler will interpret b = 16 as b = new Int32(16). The compiler will do some optimizations on code involving built-in lightweight types/primitives, like:
int a = 1 + 2;
will compile to:
int a = 3;
Sure there are another not so obvious optimizations, but I will owe you a good explanation on that.
The point is the differences between types and lightweight types (where primitives belongs to). Here is an article that discusses the differences between the two types, is a good start point: http://msdn.microsoft.com/en-us/magazine/cc301569.aspx
Upvotes: 1
Reputation: 4992
In Java, primitive types are not derived from type java.lang.Object
. As a consequence, there are additional classes (e.g. java.lang.Integer
for the int
primitive type) that wrap the primitive types, so they can be stored in reference variables.
The CLR also knows primitive types, but they are defined as structs. All structs internally derive from System.ValueType
, which in turn inherits from System.Object
. The names int
, double
, etc. in C# are just aliases for the System.Int32
, System.Double
, etc. struct types in the .NET framework. There is special handling for these types in the CLR, but unlike in Java, they are part of the unified type hierarchy.
The Java VM and the CLR are very different in this regard. In Java the types int
and java.lang.Integer
are completely independent, except for the fact that the compiler knows how to convert between them. In the CLR, there's only one type, System.Int32
, which can either appear in boxed and unboxed form.
Upvotes: 3
Reputation: 545913
That is quite wrong. In .NET, “primitive” types (= value types) do in fact derive from System.Object
. However, they do so only as far as the type system is concerned. Their treatment is still distinct from reference types.
This is simply handled by special treatment in the compiler and the runtime. The most straightforward implementation of this is that reference types are implemented via pointers to heap-allocated storage, while value types simply aren’t. However, note that this is strictly an implementation detail of Microsoft’s implementation of the CLR (.NET). Other implementations might handle this differently.
Upvotes: 1
Reputation: 499152
I understand that primitive types do not derive from Object
They do inherit from object. See System.Int32
(which is what VB.NET translates Integer
to) for example.
Just like Java, in .NET all types inherit from Object
, including primitive types.
What you see as language primitive types get translated during compilation to the corresponding CLR type that inherits from Object
.
Upvotes: 0