Debate: Is the C# primitive integer an object?

  • Thread starter Thread starter Robert Halstead
  • Start date Start date
R

Robert Halstead

Hi everyone,

My and a professor at my college (OIT) had a discussion
on whether or not the C# primitive integer, we're talking
about the "int" not the "Integer32", is an object.

We all know that when you code:

int a;

you can perform: a.toString() on that int, but does this
mean that the primitive that we all grew up with is a
object and not some value type that it was in C/C++?

My answer was no that it's not an object and something in
the framework is allowing the toString() method to be
called on all primitives. My professor's answer was yes
it was an object because of the toString() method. After
a while both sides of the argument became muddled and
questions started to point more towards how the framework
is declaring an "int" or other primitives rather than
what makes something an object.

If it is an object, I would like to know why it was
changed from a value type and how.

If it's not, I would like to prove my case that it's not
an object.

Also, if there is anywhere that can point me towards the
answer, please email me and tell me. I'll also look on
the newsgroup over the week for answers.

I was hopeing that one of the framework experts
can "school" me and him on this issue :)

Robert Halstead
 
int IS System.Int32, just a C# alias. System.Int32 is a valuetype however,
but it is derived from System.Object.

A valuetype is stored as a primitive array of bytes on the system and cannot
be derived from, etc. But it can contain methods, etc. Those methods do not
need to be stored with the data, and since value types cannot be derived
from, each instance should not need a VTable, just the type itself.

In other words, int a is ALWAYS System.Int32, it can never be MyInt32 or
anything else.
 
Daniel O'Connell said:
int IS System.Int32, just a C# alias. System.Int32 is a valuetype however,
but it is derived from System.Object.

A valuetype is stored as a primitive array of bytes on the system and cannot
be derived from, etc. But it can contain methods, etc. Those methods do not
need to be stored with the data, and since value types cannot be derived
from, each instance should not need a VTable, just the type itself.

In other words, int a is ALWAYS System.Int32, it can never be MyInt32 or
anything else.

Ugh, well, that was a lesser response than I meant for it to be.
A valuetype is as close to a primitive as you can get in .NET, the
underlying instance of a valuetype should be nothing more than the bytes it
takes to hold the data and is copied by value when passed into methods, etc.
However, ValueType is a special type of object, ValueType itself can be
derived from, generally by using the struct type in C#, however valuetypes
cannot be derived from. Because of this it is possible to have a strongly
typed valuetype that uses a primitive store but still exhibit some of the
features of an object (methods, fields, etc) while still allowing for
interop and precise memory arrangement.
 
Damn, I can't finish anything today it seems.
I should also note that in any case you want to use a valuetype as an
object, the system does provide a way to convert a valuetype to a literal
reference type object, called boxing. Read up on msdn about
System.ValueType, boxing\unboxing, etc and you should get a full explination
of the concepts.
 
-----Original Message-----

the system and
cannot Those methods do
not

Ugh, well, that was a lesser response than I meant for it to be.
A valuetype is as close to a primitive as you can get in .NET, the
underlying instance of a valuetype should be nothing more than the bytes it
takes to hold the data and is copied by value when passed into methods, etc.
However, ValueType is a special type of object, ValueType itself can be
derived from, generally by using the struct type in C#, however valuetypes
cannot be derived from. Because of this it is possible to have a strongly
typed valuetype that uses a primitive store but still exhibit some of the
features of an object (methods, fields, etc) while still allowing for
interop and precise memory arrangement.

Ok, so with this ValueType object, when stored into
memory, the only thing stored is the value and not the
remaining object data? Just like the primitive in
C/C++? Cause it would seem that by adding the object
data to it from ValueType, your really not saving much
memory between MyInt32 and the ValueType integer.
 
Thanks Mr. O'Connell.

On my last post that I posted, I answered myself. Thanks
for the quick response though :) This should clear up the
argument me and my professor had today :)
 
Robert Halstead said:
Ok, so with this ValueType object, when stored into
memory, the only thing stored is the value and not the
remaining object data? Just like the primitive in
C/C++? Cause it would seem that by adding the object
data to it from ValueType, your really not saving much
memory between MyInt32 and the ValueType integer.

Yes, in essence thats the trickery of it all. The data is stored as 4 bytes
on the stack(usually) and because every variable of type Int32 points to an
instance of type Int32 all the runtime needs to do is look up the method
table contained with the Int32 type to call a method, it never has to
consider if the valuetype has been inherited from and has extra layers of
indirection to call, hence there is no need for a object header.

Contrast these:
--value types--
//allocate 4 bytes of memory on the stack, set that to 100;
int a = 100;
//a is of type Int32, so call the Int32.ToString method, it can never be
anything but Int32.
a.ToString();
//allocate another 4 bytes and copy the value of a into it
int b = a;
//allocate 8 bytes and copy the value of a into it, note that this does not
copy a reference
long c = (long)a;
//c is of type Int64, so call Int64.ToString. This will ALWAYS call
Int64.ToString()
c.ToString();

--reference types--
//allocate MyObject on the heap
MyObject a = new MyObject();
//call MyObject.ToString
a.ToString();
//create another reference to a with type object
object b = a;
//the runtime must know what the actual instance b points to is, even though
b
//itself is of type object. so a lookup must be made and it must be
determined that
//b.ToString() is actually calling MyObject.ToString, not object.ToString.
b.ToString();


Now, if for some reason you need to treat a valuetype as an object, the
system does provide boxing as I mentioned, which wraps the valuetype into a
reference type with full header, etc, as I understand it anyway.
 
Just to clarify, both you and your professor are right. In the .Net
Framework, everything is an object -- that is, every type is derived from
the System.Object base class.

However, the object hierarchy beneath System.Object is divided into two
paths -- one for value types, and another for reference types. Reference
types are "traditional" objects that use references (pointers) to data
stored on the heap, and are destroyed through garbage collection.

Value types (like integers and structs) are "lightweight" objects that are
stored directly on the stack. For example, an integer only occupies four
bytes of memory (32 bits). When you call a method on a value type, like
..ToString, the .Net CLR (the runtime) automagically applies the correct
method.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcrefvaluetypes.asp

http://msdn.microsoft.com/library/d...pguide/html/cpconcommontypesystemoverview.asp

http://www.albahari.com/value vs reference types.html

Sometimes, when you treat a value type like an object, the CLR uses a
process called "boxing" that converts the value type object into a reference
type by storing the value type's data inside of a reference object. For
example, this occurs when you add an integer to an ArrayList (wihch stores
items as generic objects.)

http://www.geocities.com/csharpfaq/box.html

http://www.dotnetextreme.com/articles/cSharpBoxing.asp

Also, there isn't a difference between a C# int and a System.Int32 --
they're the same type.
 
Robert Halstead said:
Thanks Mr. O'Connell.
np
On my last post that I posted, I answered myself. Thanks
for the quick response though :) This should clear up the
argument me and my professor had today :)

Glad to hear I helped
 
Back
Top