SledgeHammer
SledgeHammer

Reputation: 7726

Shouldn't this work? (typecast / unboxing)

public IList A23 { get; set; }

s.A23 = new List<int>(new int[] { 62, 63, 64 });

IList g = s.A23;
double d = (double)g[0];

the double cast on the last line throws an exception. g[0] should be an object (of an int), which is castable to a double.

I know that this works:

double d = (double)(int)g[0];

But that isn't my question :). I'm working on a runtime thing which is beyond the scope of this post. Since the source is an IList, I don't know the type that's in there. I would have thought the compiler could cast the object without unboxing as an int first??

Upvotes: 2

Views: 196

Answers (2)

Eric Lippert
Eric Lippert

Reputation: 660289

the double cast on the last line throws an exception

That's correct. A boxed T may only be unboxed to T or T?.

I would have thought the compiler could cast the object without unboxing as an int first

OK, you're building a runtime, so it will build character for you to work this out. Carefully describe the code you expected the compiler to emit, remembering that of course the compiler does not know there's an int in there.

Extremely helpful hint: If the boxed object is typed as dynamic instead of object then the cast to double succeeds. That is (double)(dynamic)(g[0]) works as you expect. "Dynamic" is just "object" with a funny hat on, so why does one fail and the other succeed?

Upvotes: 4

pid
pid

Reputation: 11607

No, it cannot. Unboxing is not casting. You need to unbox the variable and then cast it. In this special case this means two casts.

When you cast to double the runtime (not the compiler!) does not know how to cast the object to double, and doesn't try to unbox it either, because there's nothing that says you want that. In fact, it would be perfectly plausible that you want the object to be cast, and not the boxed variable. The intent of your code is ambiguous and the designers may have decided to throw it altogether.

Upvotes: 2

Related Questions