Reputation: 7726
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
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
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