How do I declare a nested enum?

Viewed 52363

I want to declare a nested enum like:

\\pseudocode
public enum Animal
{
  dog = 0,
  cat = 1
}

private enum dog
{
   bulldog = 0,
   greyhound = 1,
   husky = 3
}

private enum cat
{
   persian = 0,
   siamese = 1,
   burmese = 2
}

Animal patient1 = Animal.dog.husky;

Can it be done?

12 Answers

I would probably use a combination of enumerated bit fields and extension methods to achieve this. For example:

public enum Animal
{
   None = 0x00000000,
   AnimalTypeMask = 0xFFFF0000,
   Dog = 0x00010000,
   Cat = 0x00020000,
   Alsation = Dog | 0x00000001,
   Greyhound = Dog | 0x00000002,
   Siamese = Cat | 0x00000001
}

public static class AnimalExtensions
{
  public bool IsAKindOf(this Animal animal, Animal type)
  {
    return (((int)animal) & AnimalTypeMask) == (int)type);
  }
}

Update
In .NET 4, you can use the Enum.HasFlag method rather than roll your own extension.

You can use this method to get what you want though

public static class Animal {
    public enum Dog {
        BullDog,
        GreyHound,
        Huskey
    }

    public enum Cat {
        Tabby,
        Bombbay
    }
}

Simply, no, it cannot.

I recommend that you define all of the values within the Animal enum. Is there any reason why you want this particular structure?

I don't think it works that way.

Enumerations are supposed to be a simple set of parallel values.

You may want to express that relationship with inheritance.

This solution returns int, not type. But I am using it like this:

public static class Animals
{
    public static class Vertebrates
    {
        public static class Mammals
        {
            public enum Dogs
            {
                BullDog = 0,
                Greyhound = 1
            }
            public enum Cats
            {
                persian = 0,
                Greyhound = 1
            }
        }

        public static class Birds
        {
            public enum FirstType
            {
                FirstType0 = 0,
                FirstType1 = 1
            }
            public enum SecondType
            {
                SecondType0 = 0,
                SecondType1 = 1
            }
        }
    }
}

Usage:

int i = (int)Animals.Vertebrates.Mammals.Dogs.BullDog; 
int j = (int)Animals.Vertebrates.Birds.FirstType.FirstType0;

Perhaps this would suffice?

class A
{
  public const int Foo = 0;
  public const int Bar = 1;
}

class B : A
{
  public const int Baz = 2;
}

This is my solution/work around:

public static class Categories
{
    public const string Outlink = "Outlink";
    public const string Login = "Login";
}

public enum Action
{
    /// <summary>
    /// Outlink is a anchor tag pointing to an external host
    /// </summary>
    [Action(Categories.Outlink, "Click")]
    OutlinkClick,
    [Action(Categories.Outlink, "ClickBlocked")]
    OutlinkClickBlocked,

    /// <summary>
    /// User account events
    /// </summary>
    [Action(Categories.Login, "Succeeded")]
    LoginSucceeded,
    [Action(Categories.Login, "Failed")]
    LoginFailed
}

public class ActionAttribute : Attribute
{
    public string Category { get; private set; }
    public string Action { get; private set; }
    public ActionAttribute(string category, string action)
    {
        Category = category;
        Action = action;
    }
}
Related