casting problem

F

Francois Malgreve

in the following code:

object obj = this.ViewState["currentCreditLimit"];
string s = obj.GetType().ToString();
currentCreditLimit = (double) this.ViewState["currentCreditLimit"];

ViewState is a StateBag object (dictionary type object)
the String s shows me that the type is System.Int32, the value contained is
0 ( I can see it in the debugger)

I understand well that a double can contain bigger values than what contain
an Int32 but I do not understand why I got a casting exception. As I think
that you can cast any number types into any others. The only risk being to
overflow the capacity of the target type. Which is not the case here as my
value is 0.

Also, if I do something like the following it will run fine.
int i = 0;
double d = 0;
d = i;

Could someone explain me what is going on?

Thanks

Francois
 
T

Tyler Dixon

Francois said:
in the following code:

object obj = this.ViewState["currentCreditLimit"];
string s = obj.GetType().ToString();
currentCreditLimit = (double) this.ViewState["currentCreditLimit"];

ViewState is a StateBag object (dictionary type object)
the String s shows me that the type is System.Int32, the value contained is
0 ( I can see it in the debugger)

I understand well that a double can contain bigger values than what contain
an Int32 but I do not understand why I got a casting exception. As I think
that you can cast any number types into any others. The only risk being to
overflow the capacity of the target type. Which is not the case here as my
value is 0.

Also, if I do something like the following it will run fine.
int i = 0;
double d = 0;
d = i;

Could someone explain me what is going on?

Thanks

Francois
The problem is with boxing. See, an int has to boxed to be treated as
an object. In C#, when you unbox a boxed type, you have to cast it to
the original boxed type *first*, otherwise you will get a
InvalidCastException.

Use

currentCreditLimit = (double)(int) this.ViewState["currentCreditLimit"];
 
F

Francois Malgreve

Thank you,
I always thought that one advantage of C# is that boxing and unboxing is
automatic. Then what I understand from what you say is that boxing and
unboxing is automatic except in the case I cast a value to an unboxed type
different that the native type? Which would mean I need to unbox manually :

(int) this.ViewState["currentCreditLimit"];
before being able to cast :
(double)(int) this.ViewState["currentCreditLimit"];

Or do you mean that in C# I always need to unbox manually ? That the
unboxing needs to be written in the code but that only the boxing will be
implicit?

The last thing i am not sure about:
I think that the boxed type is a reference type wrapped in an object
(typically System.Object) and the unboxed type is the value type like
System.Int32 (keyword int in c#), right?

Thanks again for your explanations,

Best regards,
Francois


Tyler Dixon said:
Francois said:
in the following code:

object obj = this.ViewState["currentCreditLimit"];
string s = obj.GetType().ToString();
currentCreditLimit = (double) this.ViewState["currentCreditLimit"];

ViewState is a StateBag object (dictionary type object)
the String s shows me that the type is System.Int32, the value contained is
0 ( I can see it in the debugger)

I understand well that a double can contain bigger values than what contain
an Int32 but I do not understand why I got a casting exception. As I think
that you can cast any number types into any others. The only risk being to
overflow the capacity of the target type. Which is not the case here as my
value is 0.

Also, if I do something like the following it will run fine.
int i = 0;
double d = 0;
d = i;

Could someone explain me what is going on?

Thanks

Francois
The problem is with boxing. See, an int has to boxed to be treated as
an object. In C#, when you unbox a boxed type, you have to cast it to
the original boxed type *first*, otherwise you will get a
InvalidCastException.

Use

currentCreditLimit = (double)(int) this.ViewState["currentCreditLimit"];
 
F

Francois Malgreve

Thank you,
I always thought that one advantage of C# is that boxing and unboxing is
automatic. Then what I understand from what you say is that boxing and
unboxing is automatic except in the case I cast a value to an unboxed type
different that the native type? Which would mean I need to unbox manually :

(int) this.ViewState["currentCreditLimit"];
before being able to cast :
(double)(int) this.ViewState["currentCreditLimit"];

Or do you mean that in C# I always need to unbox manually ? That the
unboxing needs to be written in the code but that only the boxing will be
implicit?

The last thing i am not sure about:
I think that the boxed type is a reference type wrapped in an object
(typically System.Object) and the unboxed type is the value type like
System.Int32 (keyword int in c#), right?

Thanks again for your explanations,

Best regards,
Francois


Tyler Dixon said:
Francois said:
in the following code:

object obj = this.ViewState["currentCreditLimit"];
string s = obj.GetType().ToString();
currentCreditLimit = (double) this.ViewState["currentCreditLimit"];

ViewState is a StateBag object (dictionary type object)
the String s shows me that the type is System.Int32, the value contained is
0 ( I can see it in the debugger)

I understand well that a double can contain bigger values than what contain
an Int32 but I do not understand why I got a casting exception. As I think
that you can cast any number types into any others. The only risk being to
overflow the capacity of the target type. Which is not the case here as my
value is 0.

Also, if I do something like the following it will run fine.
int i = 0;
double d = 0;
d = i;

Could someone explain me what is going on?

Thanks

Francois
The problem is with boxing. See, an int has to boxed to be treated as
an object. In C#, when you unbox a boxed type, you have to cast it to
the original boxed type *first*, otherwise you will get a
InvalidCastException.

Use

currentCreditLimit = (double)(int) this.ViewState["currentCreditLimit"];
 
J

Jon Skeet [C# MVP]

Thank you,
I always thought that one advantage of C# is that boxing and unboxing is
automatic. Then what I understand from what you say is that boxing and
unboxing is automatic except in the case I cast a value to an unboxed type
different that the native type? Which would mean I need to unbox manually :

(int) this.ViewState["currentCreditLimit"];
before being able to cast :
(double)(int) this.ViewState["currentCreditLimit"];

Or do you mean that in C# I always need to unbox manually ? That the
unboxing needs to be written in the code but that only the boxing will be
implicit?

Well, unboxing is implicit in that it's done with a normal cast rather
than you having to specify an unboxing operation, but yes, other than
that it's explicit. This is equivalent to having to cast for reference
types, too, eg

string x = (string) myHashTable["hello"];
The last thing i am not sure about:
I think that the boxed type is a reference type wrapped in an object
(typically System.Object) and the unboxed type is the value type like
System.Int32 (keyword int in c#), right?

Yes - apart from the "typically System.Object" - I believe the type of
the wrapper object is distinct from System.Object, and indeed I would
think it would *have* to be in order to tell the difference between a
plain object and a wrapped value. (And to store the data, of course.)
 
E

Eric Newton

The root of the problem is that you're not placing the proper value in to
begin with

Whatever setting ViewState["currentCreditLimit"] is setting it to an INTEGER
value. If your intention is to store a DECIMAL value then you need to be
consistent by initializing it with a DECIMAL value either explicitly (
ViewState["currentCreditLimit"]=new Decimal(0) or via the "d" specifier,
ViewState["currentCreditLimit"] = 0d

--
Eric Newton
C#/ASP Application Developer
http://ensoft-software.com/
(e-mail address removed)-software.com [remove the first "CC."]

Tyler Dixon said:
Francois said:
in the following code:

object obj = this.ViewState["currentCreditLimit"];
string s = obj.GetType().ToString();
currentCreditLimit = (double) this.ViewState["currentCreditLimit"];

ViewState is a StateBag object (dictionary type object)
the String s shows me that the type is System.Int32, the value contained is
0 ( I can see it in the debugger)

I understand well that a double can contain bigger values than what contain
an Int32 but I do not understand why I got a casting exception. As I think
that you can cast any number types into any others. The only risk being to
overflow the capacity of the target type. Which is not the case here as my
value is 0.

Also, if I do something like the following it will run fine.
int i = 0;
double d = 0;
d = i;

Could someone explain me what is going on?

Thanks

Francois
The problem is with boxing. See, an int has to boxed to be treated as
an object. In C#, when you unbox a boxed type, you have to cast it to
the original boxed type *first*, otherwise you will get a
InvalidCastException.

Use

currentCreditLimit = (double)(int) this.ViewState["currentCreditLimit"];
 

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