I have an enum, Foo:
public enum Foo { Alpha, Bravo, Charlie }
If I attempt the following cast from a boxed int to a Foo?, I get an InvalidCastException:
var x = (Foo?)(object)1;
This led me to some experimentation…
var x = (Foo)(object)1; // succeeds
var x = (long)(object)1; // fails
var x = (long?)(object)1; // fails
var x = (long)1; // succeeds
var x = (long?)1; // succeeds
var x = (int)(object)1; // succeeds
var x = (int?)(object)1; // succeeds
What this tells me is that you can cast from a boxed int to an enum but not to a long, and you cannot convert from a boxed int to any kind of nullable except an int?.
By the way, the reason I’m casting the int to object first is that I’m really trying to cast from an int to a generic parameter TValue, like this:
var x = (TValue)(object)1;
If I didn’t have (object), it wouldn’t compile. (See this blog post by Eric Lippert for details.)
Questions
-
Why can you convert from a boxed
intto an enum, but not to a nullable enum (and not to alongnor along?)? -
What’s the easiest way to rewrite
var x = (TValue)(object)1;so that it compiles, works at runtime, and is performant (assumingTValueis determined to be aFoo?at runtime)?
To answer the first question, you can convert from a boxed value to an enum only if the boxed value is of the enum’s underlying type. Had you declared
you would not be able to cast from boxed int to Foo.
To answer the second question, try
This involves boxing, though; if you need a solution that won’t box, it will be more complicated.