tags:

views:

1763

answers:

9

I have a class with a property which is an enum

The enum is

/// <summary>
/// All available delivery actions
/// </summary>
public enum EnumDeliveryAction
  {
    /// <summary>
    /// Tasks with email delivery action will be emailed
    /// </summary>
    Email,

    /// <summary>
    /// Tasks with SharePoint delivery action 
   /// </summary>
   SharePoint
  }

When I create an instance of this class, NOWHERE in the code, do I specify the value of the enum field, but it seems to default to the first item in the enumlist, and not a null value, is this how enums work? How is it possible to ensure that the enum gets some kind of null value if it is not set, I don't want it defaulting to the first value in the enum.

Thank you.

+19  A: 

Default value for enum types is 0 (which is by default, the first element in the enumeration). Fields of a class will be initialized to the default value.

If you need to represent an unknown value in the enum, you can add an element Unknown with value 0. Alternatively, you could declare the field as Nullable<MyEnum> (MyEnum?).

Mehrdad Afshari
So do I need to start my enums first value with 1?
JL
Updated the answer to reflect that.
Mehrdad Afshari
Not unless you want the default value to be undefined.. .It will still default to a value of zero, which, if your enum does not have a member with value zero, will be an illegal value..
Charles Bretana
Charles: not *illegal*. In C# (unlike Java), it's considered legal to have enum values outside the defined range.
Mehrdad Afshari
+1 You can keep your enum the same if you make it nullable by defining it as MyEnum?, or add a default value, in this case, "None", to indicate a "null" condition. I tend to prefer the second, since I think excessive use of nullable variables starts to look messy.
Will Eddins
It's a logical illegality. But that's beside the point. Back on track, FxCop will complain if you don't have an element in your `enum` with the name None. Presumably this is your default 0 value. Good habit to get into.
Matthew Scharley
+5  A: 

Enums are a value type, like ints. You need to make it nullable so as not to default to the first (or 0-defined) enum member.

public class MyClass
{
   public EnumDeliveryAction? DeliveryAction { get; set;}
}
Josh Kodroff
or add an undefined member:public enum EnumDeliveryAction {Undefined=0, Email=1, Sharepoint=2 }
Charles Bretana
You can also use Nullable
Polaris878
Polaris: `Nullable<T>` is identical to `T?`.
Mehrdad Afshari
Yes. T? is identical to Nullable<T>.
Josh Kodroff
+2  A: 

Enum fields are initialized as zero; an if you don't specify values in an enum, they start at zero (Email = 0, SharePoint=1, etc).

Thus by default any field you do initialize yourself will be Email. It is relatively common to add None=0 for such cases, or alternatively use Nullable<T>; i.e.

/// <summary>
/// All available delivery actions
/// </summary>
public enum EnumDeliveryAction
{
    /// <summary>
    /// Not specified
    /// </summary>
    None,

    /// <summary>
    /// Tasks with email delivery action will be emailed
    /// </summary>
    Email,

    /// <summary>
    /// Tasks with SharePoint delivery action 
   /// </summary>
   SharePoint
}

You should also be sure to never treat your last expected value as a default; i.e.

switch(action) {
    case EnumDeliveryAction.Email; RunEmail(); break;
    default: RunSharePoint(); break;
}

this should be:

switch(action) {
    case EnumDeliveryAction.Email; RunEmail(); break;
    case EnumDeliveryAction.SharePoint; RunSharePoint(); break;
    default: throw new InvalidOperationException(
          "Unexpected action: " + action);
}
Marc Gravell
A: 

The traditional aproach to adding a null to values that don't generally have one is to declare your variable as a nullable type, ie:

EnumDeliveryAction? action=null;
Blindy
A: 

I'd suggest having a value of None = 0 as your first enum value. Make it explicit, then you know for sure what it's value is.

BCarter
A: 

You can start your enums at any value (such as 1), but when they represent a lookup value in a Database, you generally want them to match up.

I generally declare the first Enum as None ( = 0) when it makes sense to do so, as per the .Net Framework Design guidelines.

Mitch Wheat
+1  A: 

Best practice (as advised by Code Analysis) is to always have a default value in your enums, which represent an unset value.

So in your case, you might have:

public enum EnumDeliveryAction
   {

    /// <summary>
    /// Default value
    /// </summary>
    NotSet,

    /// <summary>
    /// Tasks with email delivery action will be emailed
    /// </summary>
    Email,

    /// <summary>
    /// Tasks with SharePoint delivery action 
   /// </summary>
   SharePoint
  }

As an aside, you shouldn't prefix the name of the enum with Enum. You might consider changing to:

public enum DeliveryAction;
Winston Smith
I'm not so sure I agree with adding an "Undefined" enum member in .Net since that's what null means by definition - unknown. Seems redundant to redefine null in every enum you create.
Josh Kodroff
A: 

By default only reference types are nullable types. If you want a variable to allow nulls you have to define it as nullable using the "?" character (for this you need C# 2.0 or up).

enum MyEnum
{
    ValueOne,
    ValueTwo
}

and in your class

MyEnum? myvariable = null;
monkey_p
I think you mean that only *reference types* are nullable by default, as both reference and value types are considered objects in .NET
PatrickJ
ye, that's what i meant :D
monkey_p
A: 

Enums are value types. Value types cannot be null and are initialized to 0.

Even if your enum does not have a 0, enum variables will be initialized to 0.

public enum SomeEnum
{
    A = 1,
    B = 2
}

(later)

SomeEnum x = default(SomeEnum);
Console.WriteLine(x);

Outputs - 0


Some answerers are advocating using Nullable<T> to match your initialization expectations. Becareful with this advice since Nullable<T> is still a value type and has different semantics than reference types. For example, it will never generate a null reference exception (it's not a reference).

SomeEnum? x = default(SomeEnum?);

if (x == null)
{
    Console.WriteLine("It's null!");
}
if (x > SomeEnum.B)
{
}
else
{
    Console.WriteLine("This runs even though you don't expect it to");
}
David B