-1

I was working with a small piece of code in Sharepoint, that goes like this:

int? do_ = (int?)re["mi"]; // consider "re" a dictionary<string, object>;

The expression to the right of the equal sign evaluates to a Double. To make double sure, I double-checked it (:D) in the watch window. And yeah, it's a System.Double, in and out.

However, that line throws an exception:

Specified cast is not valid.

I was about to make a dent on my desk with my forehead when it dawned on me that yes, you can cast double to int, though losing the non-integer part of the value (which is actually intended in my case). I learned this in my first days of programming, before the world moved on.

So to be even more sure, I created another solution, a simple console app. I put this code into it:

double dragon = 2.0;
int? i = (int?)dragon;

And it works, just as expected.

Why would it work in one setting but fail in the other one?

Geeky Guy
  • 9,229
  • 4
  • 42
  • 62

3 Answers3

9

This is a very frequently asked question. You cannot unbox a boxed T to anything other than T or T?.

I explain why here:

http://ericlippert.com/2009/03/03/representation-and-identity/

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
2

But this should work for you

(int?)(double)re["mi"];

Edit1 Above code will work if boxed type is double and doesn't work if it is double? to make it work do the following

(int?)(double?)re["mi"];
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • 1
    Don't you think it should be `(int?)(double?)re["mi"]` - if the `object` reference is not a box with a `double` but actually a `null` reference, you need nullables all the way. Maybe inefficient, though. – Jeppe Stig Nielsen Jul 15 '13 at 21:02
  • @JeppeStigNielsen yeah but in question he mentioned that it was a double – Sriram Sakthivel Jul 15 '13 at 21:04
  • @JeppeStigNielsen: First off, this is unlikely to be the bottleneck. Second, Roslyn does a pretty good job of optimizing nested lifted conversions, though the original-recipe C# compiler is less good. See my series of articles http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/ describing how the nullable arithmetic optimizer works. Part for in particular is germane. – Eric Lippert Jul 15 '13 at 21:04
  • @EricLippert I don't think it will be a bottleneck either. But I might still write `object reMi = re["mi"]; int? do = reMi == null ? (int?)null : (int)(double)reMi;`. You never know with the "original-recipe" compiler ;-) – Jeppe Stig Nielsen Jul 15 '13 at 21:27
0

This is because you trying to cast object into integer. your decimal value is boxed.

Conciser this:

object o = 2.0d;

int i = (int)((double) o); // This will work
T.S.
  • 18,195
  • 11
  • 58
  • 78