Search code examples
c#asp.netenumsnullable

Nullable enums does not contain error


I would like to create my enums as nullable rather than add a default entry with a default of 0.

However, in the following scenario I get syntax errors and I can't understand why, or how to fix it at the moment. It's probably something simple, but the simplest things...

Here's my properties that decare enums as nullable:

public Gender? Gender { get; private set; }

public MaritalStatus? MaritalStatus { get; private set; }

Here's a method that is giving me the syntax error, which is Gender does not contain..., MaritalStatus does not contain...:

    string GetTitle()
    {
        if (Gender == null || MaritalStatus == null)
            return null;
        if (Gender == Gender.M) // Error here!
            return "Mr";
        else if (
            MaritalStatus == MaritalStatus.Married ||
            MaritalStatus == MaritalStatus.Separated ||
            MaritalStatus == MaritalStatus.Widowed) // Error here!
            return "Mrs";
        else
            return "Ms";
    }

Any advice appreciated.


Solution

  • You have enums MaritalStatus and Gender. At the same time, you have properties named MaritalStatus and Gender. You need to avoid this.

    Here:

    if (Gender == Gender.M)
    if (MaritalStatus == MaritalStatus.Married)
    

    the syntax is incorrect since Gender and MaritalStatus are recognized as variables, but not as type.
    Moreover, you need to use .Value to access a value of Nullable.

    So, you can explicitly specify the namespace:

    if (Gender.Value == YourNamespace.Gender.M)
    if (MaritalStatus.Value == YourNamespace.MaritalStatus.Married)
    

    but I strongly recommend to rename your enums to GenderEnum and MaritalStatusEnum.

    Why does it happen?

    This problem is simply reproducable here:

    enum SameName { Value }
    class Tester
    {
       void Method1() {
          SameName SameName;
          SameName test = SameName.Value; // Works!
       }
       void Method2() {
          string SameName;
          SameName test = SameName.Value; // Doesn't work! Expects string method Value
       }
    }
    

    In this answer Eric Lippert has described the reason of this:

    C# was designed to be robust in the face of a property named the same as its type because this is common:

    class Shape
    {
        public Color Color { get; set; }
        ...
    

    If you have a type Color, it is very common to have a property also called Color, and there's no good way to rename either of them. Therefore C# was designed to handle this situation reasonably elegantly.

    So, if your variable is of type Enum, then it refers to the enum member; else - it refers to variable. Enum? belongs to "else".