Type.IsValueType

B

Brette.Net

Hello All,

I was doing a little messing around with some type conversion they
other day. Code is below.

struct ValueStruct
{
int a;

public ValueStruct(int inA)
{
a = inA;
}
}

public class Runner
{
public static void Main()
{
ValueStruct mValueStruct = new ValueStruct(10);
Console.WriteLine(mValueStruct.GetType().IsValueType);

Console.WriteLine(mValueStruct.ToString());
Console.WriteLine(mValueStruct.GetType().IsValueType);
}
}

My understanding is that if you call ToString() or any of the Object
virtual methods on a value type, the actual value type has to be
boxed. This makes sense as the base implementations of these methods
are on the System.Object type.

However, I noticed that calling the IsValueType after the ToString()
call still returns true. I understand why this happening because after
all it is still a struct thus it impl of IsValueType will be true.

So is there a better way to determine if an object is a value type or
a reference type? Obviously in this case the IsValueType is not really
telling me the correct information.

Thanks,
B
 
J

Jon Skeet [C# MVP]

My understanding is that if you call ToString() or any of the Object
virtual methods on a value type, the actual value type has to be
boxed.

Only if the method isn't overridden.
This makes sense as the base implementations of these methods
are on the System.Object type.

No - there's no need to box if the implementation is known at compile
time.
However, I noticed that calling the IsValueType after the ToString()
call still returns true. I understand why this happening because after
all it is still a struct thus it impl of IsValueType will be true.

Indeed - and even if boxing did occur, that wouldn't change anything
about your original variable.
So is there a better way to determine if an object is a value type or
a reference type? Obviously in this case the IsValueType is not really
telling me the correct information.

Yes it is - although it doesn't always. Here's a better example of
where it doesn't:

int x = 5;
object o = x;
Console.WriteLine(o.GetType().IsValueType);

Here you really are asking a boxed value for its type - so in some
senses it should return false instead of true.

In fact, as GetType() itself isn't virtual, it *will* always (AFAIK)
involve boxing, so it would be impossible to distinguish between the
unboxed and the boxed type. I don't believe the framework libraries
allow you to distinguish between the two, I'm afraid.

Why do you need this information?

Jon
 
J

J2EE Convert

Jon,

Thanks for the reply I visit your site almost daily so I feel like
this is a brush with fame ;-)
Only if the method isn't overridden.

Yes I understand this and in my example you will see I do not override
it thus my assumption is that boxing would have happened.
No - there's no need to box if the implementation is known at compile
time.

If the boxing is not necessary for the call to the Object.ToString()
why does it happen? I guess I just assumed that was the reason.
Why do you need this information?

General curiosity I guess. I working towards my certs and thus my
reading ends up leading to more questions then answers. Your site has
been a huge help though! I actually print out an article a day and
bring it to lunch for some reading ;-)

Thanks,
B
Indeed - and even if boxing did occur, that wouldn't change anything
about your original variable.

Are you saying that boxing did not take place? "and even if boxing did
occur" The call to ToString() at least in what I have read will result
in boxing unless overridden in the type in question. In my example I
did not provide an impl thus would it not be boxed? Sorry if I
misunderstood your answer.
 
J

Jon Skeet [C# MVP]

J2EE Convert said:
Thanks for the reply I visit your site almost daily so I feel like
this is a brush with fame ;-)

LOL - I'm really very, very ordinary.
Yes I understand this and in my example you will see I do not override
it thus my assumption is that boxing would have happened.

Yes, you're right in this case. I should have read your sample code
more closely!
If the boxing is not necessary for the call to the Object.ToString()
why does it happen? I guess it just assumed that was the reason.

It happens if the compiler needs to call it as a virtual call, but in
the case where the value type provides the implementation, the compiler
knows that there won't be any further overriding (due to the nature of
value types) so it can make a non-virtual call, thus avoiding boxing.
General curiosity I guess. I working towards my certs and thus my
reading ends up leading to more questions then answers. Your site has
been a huge help though! I actually print out an article a day and
bring it to lunch for some reading ;-)

That's almost scary... but in a good way :)
 
B

Brette.Net

LOL - I'm really very, very ordinary.



Yes, you're right in this case. I should have read your sample code
more closely!



It happens if the compiler needs to call it as a virtual call, but in
the case where the value type provides the implementation, the compiler
knows that there won't be any further overriding (due to the nature of
value types) so it can make a non-virtual call, thus avoiding boxing.



That's almost scary... but in a good way :)

Thanks Jon!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top