tags:

views:

124

answers:

5

I have the following:

MyEnum? maybeValue = GetValueOrNull();

if (null != maybeValue)
{
    MyEnum value = (MyEnum)maybeValue;
}

What I want to know is if that explicit (MyEnum) cast is necessary on an instance of type MyEnum?. This seems like a simple question, I just felt paranoid that there could possibly be some runtime error if I just did MyEnum value = maybeValue within that if statement.

+8  A: 

For a nullable type, you can do

if (maybeValue.HasValue)
{
    MyEnum value = maybeValue.Value;
}
Aequitarum Custos
great minds think alike.
Jason D
+3  A: 

I believe that when you define a variable as a nullable type, it adds a .HasValue property and a .Value property. You should be able to use those to avoid any casting.

You can rewrite your code like this

MyEnum? maybeValue = GetValueOrNull();

if (maybeValue.HasValue == true)
{
    MyEnum value = maybeValue.Value;
}
Nate Bross
+6  A: 

Since you're using nullable types, try using

if(maybeValue.HasValue)
{
    MyEnum value = maybeValue.Value;  // no cast needed! Yay!
}
Jason D
+1 vote for being a mind reader.
Aequitarum Custos
+3  A: 

Another option would be to set up your enum to have a Default (0) value and then you would be able to just do the following:

MyEnum value = GetValueOrNull().GetValueOrDefault();

However, this would require that your code have knowledge of what the default value means and possibly handle it differently from what the other enum types do.

Adam Gritt
+1 for a neat trick I didn't know about previously. I'll have to inspect code at work to see if we can benefit from this.
Jason D
+4  A: 

A number of answers have noted that using the Value property avoids the cast. This is correct and it answers the question:

is that explicit (MyEnum) cast necessary on an instance of type "MyEnum?" ?

However, we haven't addressed the other concern:

I just felt paranoid that there could possibly be some runtime error if I just did MyEnum value = maybeValue within that if statement.

Well, first off, you cannot simply assign a nullable value to a variable of its underlying type. You have to do something to do the conversion explicitly.

However, if you do so in the manner you describe -- checking whether there is a value first -- then this is safe. (Provided of course that no one is mutating the variable containing the nullable value between the call to HasValue and the fetch of the value.)

If you use ILDASM or some other tool to examine the generated code you will discover that casting a nullable value to its underlying type is simply generated as an access to the Value property; using the cast operator or accessing the Value property is a difference which actually makes no difference at all. The Value property accessor will throw if HasValue is false.

Use whichever syntax you feel looks better. I personally would probably choose the "Value" syntax over the cast syntax because I think it reads better to say "if it has a value, gimme the value" than "if it has a value, convert it to its underlying type".

Eric Lippert
Thanks for describing the difference (or lack thereof) between testing nullness and casting versus using `HasValue`/`Value`.
Sarah Vessels