Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerate with return type other than string?

Tags:

c#

enums

Since enumeration uses integers, what other structure can I use to give me enum-like access to the value linked to the name:

[I know this is wrong, looking for alternative]

private enum Project     {         Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"),         Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"),         Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"),         Sales = new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435"),         Replacement = new Guid("11E5CBA2-EDDE-4ECA-BDFD-63BDBA725C8C"),         Modem = new Guid("6F686C73-504B-111-9A0B-850C26FDB25F"),         Audit = new Guid("30558C7-66D9-4189-9BD9-2B87D11190"),         Queries = new Guid("9985242-516A-4151-B7DD-851112F562")     } 

EDIT 2014-07-20

This is a newer answer to this question. Using the Attribute class with a helper method, define the extra attributes needed on your enum.

 public enum MultiValueEnum     {         [FooAttribute("alpha", 20d, true)]         First,         [FooAttribute("beta", 40.91d, false)]         Second,         [FooAttribute("gamma", 1.2d, false)]         Third,     }         public class FooAttribute : Attribute             {                 internal FooAttribute(string name, double percentage, bool isGood)                 {                     this.Name = name;                     this.Percentage = (decimal)percentage;                     this.IsGood = isGood;                 }                 public string Name { get; private set; }                 public decimal Percentage { get; private set; }                 public bool IsGood { get; private set; }             }      public static TAttribute GetAttribute<TAttribute>(this Enum value)         where TAttribute : Attribute         {             var type = value.GetType();             var name = Enum.GetName(type, value);             return type.GetField(name)                 .GetCustomAttributes(false)                 .OfType<TAttribute>()                 .SingleOrDefault();         } 

Which makes it this easy:

        MultiValueEnum enumVar = MultiValueEnum.First;         var enumStringValue = enumVar.GetAttribute<FooAttribute>().Name;         var enumValueDecimal = enumVar.GetAttribute<FooAttribute>().Percentage;         var enumBool = enumVar.GetAttribute<FooAttribute>().IsGood; 
like image 388
callisto Avatar asked Jul 08 '09 10:07

callisto


People also ask

Can enum have string values?

The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.

How to use enum parse?

Parse<TEnum>(String, Boolean)Converts the string representation of the name or numeric value of one or more enumerated constants specified by TEnum to an equivalent enumerated object. A parameter specifies whether the operation is case-insensitive.

Do enums have to be sequential?

There is nothing that requires them to be sequential. Your enum definition is fine and will compile without issue.

How does enumerate work in C#?

An enumeration is a set of named integer constants. An enumerated type is declared using the enum keyword. C# enumerations are value data type. In other words, enumeration contains its own values and cannot inherit or cannot pass inheritance.


2 Answers

Otherwise you could create a custom Attribute for your enum, which can hold the Guid.

Something alongside these lines:

class EnumGuid : Attribute {     public Guid Guid;      public EnumGuid(string guid)     {         Guid = new Guid(guid);     } } 

And you'd then use it like so:

enum Project {     [EnumGuid("2ED3164-BB48-499B-86C4-A2B1114BF1")]     Cleanup = 1,     [EnumGuid("39D31D4-28EC-4832-827B-A11129EB2")]     Maintenance = 2     // and so forth, notice the integer value isn't supposed to be used,      // it's merely there because not assigning any value is a performance overhead. } 

And finally you could (I always do this) create an extension for easily getting the guid:

static Guid GetEnumGuid(this Enum e) {     Type type = e.GetType();      MemberInfo[] memInfo = type.GetMember(e.ToString());      if (memInfo != null && memInfo.Length > 0)     {         object[] attrs = memInfo[0].GetCustomAttributes(typeof(EnumGuid),false);         if (attrs != null && attrs.Length > 0)             return ((EnumGuid)attrs[0]).Guid;     }      throw new ArgumentException("Enum " + e.ToString() + " has no EnumGuid defined!"); } 

So in the end all you have to with your enums is:

Guid guid = Project.Cleanup.GetEnumGuid(); 

I use this approach to attach descriptions to enums, typically longer strings containing spaces, which thus cannot be used as names.

like image 156
Steffen Avatar answered Sep 21 '22 12:09

Steffen


I've seen this method (struct) used by SubSonic to store Column and Table names.

internal struct Project {    public static Guid  Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1");    public static Guid  Maintenance = new Guid("39D31D4-28EC-4832-827B-A129EB2");    public static Guid  Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1");    public static Guid  Sales = new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435");    public static Guid  Replacement = new Guid("11E5CBA2-EDDE-4ECA-BD63-B725C8C");    public static Guid  Modem = new Guid("6F686C73-504B-111-9A0B-850C26FDB25F");    public static Guid  Audit = new Guid("30558C7-66D9-4189-9BD9-2B87D11190");    public static Guid  Queries = new Guid("9985242-516A-4151-B7DD-851112F562"); } 

EDIT:- Thanks for commenting on deficiencies in code. In first place it will compile if the Guid strings are not invalid. As for not create instances to access variables yes they need to be public static

like image 36
TheVillageIdiot Avatar answered Sep 19 '22 12:09

TheVillageIdiot