Top enums Questions

List of Tags
730
Ian Boyd

How can you enumerate a enum in C#?

e.g. the following does not compile:

public enum Suit
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod()
{
    foreach (Suit suit in Suit)
    {
        DoSomething(suit);
    }
}

It gives the compile time error:

'Suit' is a 'type' but is used like a 'variable'

It fails on the Suit keyword, the 2nd one.

Answered By: jop ( 1105)
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}
583
sectrean

I'm mainly a C# developer, but I'm currently working on a project in Python.

What's the best way to implement the equivalent of an enum in Python?

Answered By: Alec Thomas ( 505)

Here's yet another way:

def enum(**enums):
    return type('Enum', (), enums)

Used like so:

>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'

You can also easily support automatic enumeration with something like this:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

Used like so:

>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1

Support for converting the values back to names can be added this way:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    reverse = dict((value, key) for key, value in enums.iteritems())
    enums['reverse_mapping'] = reverse
    return type('Enum', (), enums)

Obviously, this overwrites anything with that name, but it is useful for rendering your enums in output. It will throw KeyError if the reverse mapping doesn't exist. With the first example:

>>> Numbers.reverse_mapping['three']
'THREE'
479
lomaxx

What's a quick and easy way to cast an int to an enum in C#?

Answered By: FlySwat ( 696)

From a string:

YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);

From an int:

YourEnum foo = (YourEnum)yourInt;

Update : From number you can also:

YourEnum foo = Enum.ToObject(typeof(YourEnum) , yourInt);
428
Craig

I don't think I fundamentally understand what an enum is, and when to use it.

For example:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

What is really being declared here?

Answered By: Adam Rosenfield ( 888)

Three things are being declared here: an anonymous enumerated type is declared, ShapeType is being declared a typedef for that anonymous enumeration, and the three names kCircle, kRectangle, and kOblateSpheroid are being declared as integral constants.

Let's break that down. In the simplest case, an enumeration can be declared as

enum tagname { ... };

This declares an enumeration with the tag tagname. In C and Objective-C (but not C++), any references to this must be preceded with the enum keyword. For example:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

In order to avoid having to use the enum keyword everywhere, a typedef can be created:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

This can be simplified into one line:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

And finally, if we don't need to be able to use enum tagname with the enum keyword, we can make the enum anonymous and only declare it with the typedef name:

typedef enum { ... } tagname;

Now, in this case, we're declaring ShapeType to be a typedef'ed name of an anonymous enumeration. ShapeType is really just an integral type, and should only be used to declare variables which hold one of the values listed in the declaration (that is, one of kCircle, kRectangle, and kOblateSpheroid). You can assign a ShapeType variable another value by casting, though, so you have to be careful when reading enum values.

Finally, kCircle, kRectangle, and kOblateSpheroid are declared as integral constants in the global namespace. Since no specific values were specified, they get assigned to consecutive integers starting with 0, so kCircle is 0, kRectangle is 1, and kOblateSpheroid is 2.

313
Malachi

Say I have an enum which is just

public enum Blah {
  A, B , C, D
}

and I would like to find the enum value of a string of for example "A" which would be Blah.A. How would it be possible to do this?

Is the Enum.ValueOf() the method I need? If so, how would I use this?

Answered By: Michael Myers ( 363)

Yes, Blah.valueOf("A") will give you Blah.A.

The static methods valueOf() and values() are created at compile time and do not appear in source code. They do appear in Javadoc, though; for example, Dialog.ModalityType shows both methods.

265
David Citron

What is the preferred syntax for defining enums in JavaScript? Something like:

my.namespace.ColorEnum = {
    RED : 0,
    GREEN : 1,
    BLUE : 2
}

// later on

if(currentColor == my.namespace.ColorEnum.RED) {
   // whatever
}

Or is there a more preferable idiom?

Answered By: Gareth ( 111)

This isn't much of an answer, but I'd say that works just fine, personally

Having said that, since it doesn't matter what the values are (you've used 0, 1, 2), I'd use a meaningful string in case you ever wanted to output the current value.

232
user29964

I have the following enumeration:

public enum AuthenticationMethod
{
    FORMS = 1,
    WINDOWSAUTHENTICATION = 2,
    SINGLESIGNON = 3
}

The problem however is that I need the word "FORMS" when I ask for AuthenticationMethod.FORMS and not the id 1.

I have found the following solution for this problem (link):

First I need to create a custom attribute called "StringValue":

public class StringValue : System.Attribute
{
    private string _value;

    public StringValue(string value)
    {
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }

}

Then I can add this attribute to my enumerator:

public enum AuthenticationMethod
{
    [StringValue("FORMS")]
    FORMS = 1,
    [StringValue("WINDOWS")]
    WINDOWSAUTHENTICATION = 2,
    [StringValue("SSO")]
    SINGLESIGNON = 3
}

And off course I need something to retrieve that StringValue:

    public static class StringEnum
{
    public static string GetStringValue(Enum value)
    {
        string output = null;
        Type type = value.GetType();

        //Check first in our cached results...

        //Look for our 'StringValueAttribute' 

        //in the field's custom attributes

        FieldInfo fi = type.GetField(value.ToString());
        StringValue[] attrs =
           fi.GetCustomAttributes(typeof(StringValue),
                                   false) as StringValue[];
        if (attrs.Length > 0)
        {
            output = attrs[0].Value;
        }

        return output;
    }
}

Good now I've got the tools to get a string value for an enumerator. I can then use it like this:

string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);

Owkay now all of this works like charm but I find it a whole lot of work. I was wondering if there isn't a better solution for this.

I also tried something with a dictionary and static properties but that wasn't that good either.

Answered By: Jakub Šturc ( 213)

Try type-safe-enum pattern.

public sealed class AuthenticationMethod {

    private readonly String name;
    private readonly int value;

    public static readonly AuthenticationMethod FORMS = new AuthenticationMethod (1, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION = new AuthenticationMethod (2, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON = new AuthenticationMethod (3, "SSN");        

    private AuthenticationMethod(int value, String name){
        this.name = name;
        this.value = value;
    }

    public override String ToString(){
        return name;
    }

}

Update Explicit (or implicit) type conversion can be done by

  • adding static field with mapping

    private static readonly Dictionary<string, AuthenticationMethod> instance = new Dictionary<string,AuthenticationMethod>();
    
  • filling this mapping in instance constructor

    instance[name] = this;
    
  • and adding user-defined type conversion operator

    public static explicit operator AuthenticationMethod(string str)
    {
        AuthenticationMethod result;
        if (instance.TryGetValue(str, out result))
            return result;
        else
            throw new InvalidCastException();
    }
    
221
johnc

I'm building a function to extend the Enum.Parse concept that

  • Allows a default value to be parsed in case that an Enum value is not found
  • Is case insensitive

So I wrote the following:

public static T GetEnumFromString<T>(string value, T defaultValue) where T : Enum
{
    if (string.IsNullOrEmpty(value)) return defaultValue;
    foreach (T item in Enum.GetValues(typeof(T)))
    {
        if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
    }
    return defaultValue;
}

I am getting a Error Constraint cannot be special class 'System.Enum'.

Fair enough, but is there a workaround to allow a Generic Enum, or am I going to have to mimic the Parse function and pass a type as an attribute, which forces the ugly boxing requirement to your code.

EDIT All suggestions below have been greatly appreciated, thanks.

Have settled on (I've left the loop to maintain case insensitivity - I am usng this when parsing XML)

public static class EnumUtils
{
    public static T ParseEnum<T>(string value, T defaultValue) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");
        if (string.IsNullOrEmpty(value)) return defaultValue;

        foreach (T item in Enum.GetValues(typeof(T)))
        {
            if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
        }
        return defaultValue;
    }
}
Answered By: Vivek ( 194)

Since Enum Type implements IConvertible interface, a better implementation should be something like this:

public T GetEnumFromString<T>(string value) where T : struct, IConvertible
{
   if (!typeof(T).IsEnum) 
   {
      throw new ArgumentException("T must be an enumerated type");
   }

   //...
}

This will still permit passing of value types implementing IConvertible. The chances are rare though.

212
divinci

Possible Duplicate:
How to enumerate an enum?

public enum Foos { A, B, C }

Is there a way to loop through the possible values of Foo?

Basically?

foreach(Foo in Foos)
Answered By: JaredPar ( 289)

Yes you can use the GetValues method

var values = Enum.GetValues(typeof(Foos));

Or the typed version

var values = Enum.GetValues(typeof(Foos)).Cast<Foos>();

I long ago added a helper function to my private library for just such an occasion

public static class EnumUtil {
  public static IEnumerable<T> GetValues<T>() {
    return Enum.GetValues(typeof(T)).Cast<T>();
  }
}

Usage:

var values = EnumUtil.GetValues<Foos>();
190
Matt Ball

I know that Java enums are compiled to classes with private constructors and a bunch of public static members. When comparing two members of a given enum, I've always used .equals(), e.g.

public useEnums(SomeEnum a)
{
    if(a.equals(SomeEnum.SOME_ENUM_VALUE))
    {
        ...
    }
    ...
}

However, I just came across come code that uses the equals operator == instead:

public useEnums2(SomeEnum a)
{
    if(a == SomeEnum.SOME_ENUM_VALUE)
    {
        ...
    }
    ...
}

I've been programming in Java for 5+ years, and I thought I understood difference between the two - but I'm still scratching my head at which one is more correct. Which operator is the one I should be using?

Answered By: Reverend Gonzo ( 175)

Both are technically correct. If you look at the source code for .equals(), it simply defers to ==.

I use ==, however, as that will be null safe.