Casting question

R

Robin

Lets:

short i = 10;
object x = i;

This cast fails (invalid cast exception):

int j = (int) x;

But this one is ok:

int j = (short)x;

Why the first cast fails?
 
A

Arne Vajhøj

Lets:

short i = 10;
object x = i;

This cast fails (invalid cast exception):

int j = (int) x;

But this one is ok:

int j = (short)x;

Why the first cast fails?

In general you can not cast to something that is not the
same type or a super type of the actual type.

Arne
 
R

Robin

In general you can not cast to something that is not the
same type or a super type of the actual type.

Arne

I don't quite get it.

int j = (int) x;

x is short, a numeric and being cast to int so no loss of precision.

Why this works then:

int j = (short)x;

OK, so you first cast x to short, but then it is cast to int.
 
A

Arne Vajhøj

I don't quite get it.

int j = (int) x;

x is short, a numeric and being cast to int so no loss of precision.

Try read:

int j = (int) x;

as:

temporary int = (consider this to be an int)x // this gives an exception
unless x is either an int or a super type of int
int j = temporary int
Why this works then:

int j = (short)x;

OK, so you first cast x to short, but then it is cast to int.

And:

temporary short = (consider this to be a short)x // this gives an
exception unless x is either a short or a super type of short
int j = temporary short // this is where no loss of precision comes in

Arne
 
A

Anton Shepelev

Robin:
Lets:

short i = 10;
object x = i;

This cast fails (invalid cast exception):

int j = (int) x;

But this one is ok:

int j = (short)x;

Why the first cast fails?

In C# the '(type)value' syntax is used for both
casting and type conversion. When applied to an ob-
ject, it works as casting. Since x contains a
short, it cannot be cast as an int. But you can
cast and then convert the type as per:

short i = 10;
object x = i;
int j = ( int )( short )x;

where '( short )' casts and '( int )' converts type.
 
A

Arne Vajhøj

Robin:

In C# the '(type)value' syntax is used for both
casting and type conversion. When applied to an ob-
ject, it works as casting. Since x contains a
short, it cannot be cast as an int. But you can
cast and then convert the type as per:

short i = 10;
object x = i;
int j = ( int )( short )x;

where '( short )' casts and '( int )' converts type.

Terminology can be tricky.

The distinction between cast for references/pointers
and conversion for values is common.

But I think it is OK to call both for cast in C# given
that the C# spec says:

<quote>
7.7.6 Cast expressions
A cast-expression is used to explicitly convert an expression to a given
type.
cast-expression:
( type ) unary-expression
A cast-expression of the form (T)E, where T is a type and E is a
unary-expression, performs an explicit conversion (§6.2) of the value of
E to type T. If no explicit conversion exists from E to T, a
binding-time error occurs. Otherwise, the result is the value produced
by the explicit conversion. The result is always classified as a value,
even if E denotes a variable.
</quote>

<quote>
6.2.1 Explicit numeric conversions
....
Because the explicit conversions include all implicit and explicit
numeric conversions, it is always possible to convert from any
numeric-type to any other numeric-type using a cast expression (§7.7.6).
</quote>

Arne
 
A

Anton Shepelev

Arne Vajhoj:
Terminology can be tricky.

The distinction between cast for references/pointers
and conversion for values is common.

But I think it is OK to call both for cast in C# given
that the C# spec says:

<quote>
7.7.6 Cast expressions
A cast-expression is used to explicitly convert an expression to a given
type.
cast-expression:
( type ) unary-expression
A cast-expression of the form (T)E, where T is a type and E is a
unary-expression, performs an explicit conversion (6.2) of the value of
E to type T. If no explicit conversion exists from E to T, a
binding-time error occurs. Otherwise, the result is the value produced
by the explicit conversion. The result is always classified as a value,
even if E denotes a variable.
</quote>

<quote>
6.2.1 Explicit numeric conversions
...
Because the explicit conversions include all implicit and explicit
numeric conversions, it is always possible to convert from any
numeric-type to any other numeric-type using a cast expression (7.7.6).
</quote>

Thanks. Your usage is correct from the standard's
viewpoint, but intuitively I understand casting as
looking at the same thing from a different view-
point. In this way, one can cast pointers and
thereby view the addressed memory as containing one
or another sturcture. This implies no conversion,
no processing, and does not take even a single CPU
instruction.

Standard authors were forced to use the same term
for type conversion because in C# it shares its syn-
tax with casting proper, although I should prefer
Pascal's approach, i.e.:

int i;
byte b = 4;
i = int(b);

I think it would save a lot of confusion.
 
X

x

OK, thanks for the explanation.

Convert works with no problem.

short i = 10;
object x = i;
int j = Convert.ToInt32(x);

Is Convert (much) slower than cast?
 
A

Arne Vajhøj

OK, thanks for the explanation.

Convert works with no problem.

short i = 10;
object x = i;
int j = Convert.ToInt32(x);

Is Convert (much) slower than cast?

Relative (comparing billions of Convert calls with cast) probably.

Absolute (making a difference for your application) unlikely.

But I would recommend against it anyway.

It is a less type safe construct. It tries to come up with a
result in situations where an exception may have been more
appropriate.

Arne
 

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