1

I want to consume some files and I need to know where to put each of the data. One column is called "Category".

I can have many categories and I want to build an enum to support them.

public enum GasKeyWords
       {
           Gas,
           Fuel,
           Gas&Fuel
       }

 public enum EducationKeyWord
 {
    Education,
    Books&Supplies,
    StudentLoan
    Tuition
 }

I am thinking of something like this

 foreach(var r in records)
 {
      Categories.GasKeyWords GasKeyWords;

      bool valid = Enum.TryParse<Categories.GasKeyWords>(r, out GasKeyWords);

       if (valid)
        {
                // add to group
        }
 }

and keep using TryParse till I find a group it can parse too. I am not sure if this is the best way to do it(I am always open to better ideas).

However the problem I facing right now is that I can't use "&" in enum names. I don't have control of these category names so I can't change it.

chobo2
  • 83,322
  • 195
  • 530
  • 832
  • 11
    What about "and" (e.g., "BooksAndSupplies") – Bob Kaufman Jan 12 '12 at 00:08
  • possible duplicate of [C# using numbers in an enum](http://stackoverflow.com/questions/3916914/c-sharp-using-numbers-in-an-enum) – Kirk Woll Jan 12 '12 at 00:13
  • @BobKaufman - I don't have control over the names. I suppose before I try to parse it an enum I could do a replace and see if there are any "&" and make it into "And" – chobo2 Jan 12 '12 at 00:13
  • possible duplicate of [C# Getting Enum values ](http://stackoverflow.com/questions/1008090/c-sharp-getting-enum-values) – Jim Mischel Jan 12 '12 at 00:14
  • I posted an answer but after rereading your question, that you have no control it seems my answer might not be applicable. Sorry about that. – Dmitriy Khaykin Jan 12 '12 at 00:23
  • You could also look at [Enum with string values](http://weblogs.asp.net/stefansedich/archive/2008/03/12/enum-with-string-values-in-c.aspx). – MPelletier Jan 12 '12 at 00:31
  • Although with chobo2's last statement it sounds like he needs a dictionary more than an Enum... – MPelletier Jan 12 '12 at 00:32
  • @MPelletier - ya now I am thinking more of hardcoding(and maybe in future moving to a db) that will loading into a couple dictionaries) – chobo2 Jan 12 '12 at 17:06

3 Answers3

4

Why not use the Description tag to work around this problem. Granted it is not exactly what it was designed for but if you take issue with that then you can always invent your own attribute class.

Here is a quick a dirty method I wrote for getting the description attribute of a object

    public static string GetDescription(this object enumeration)
    {
        //Again, not going to do your condition/error checking here.
        //Normally I would have made this extension method for the Enum type
        but you won't know the type at compile time when building the list of descriptions but ..
        // you will know its an object so that is how I cheated around it.

        var desc = enumeration.GetType().GetMember(enumeration.ToString())[0]
            .GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];

        if (desc != null && desc.Length > 0)
        {
            return desc[0].Description;
        }

        return enumeration.ToString();
    }

Here is a quick a dirty utility method to get a list of all descriptors of an object as a list

public static IList<string> GetDescriptions<E>(E type)
{
    //I'm not going to do your error checking for you. 
    //Figure out what you want to do in the event that this isn't an enumeration. 
    //Or design it to support different cases. =P

    var list = new List<string>(); 
    foreach(var name in Enum.GetNames(typeof(E)))
    {
        var enumObj = (E) Enum.Parse(typeof(E), name);
        list.Add(enumObj.GetDescription());
    }
    return list;
}

Now for utilizing these to the effect you need

   public enum GasKeyWords
   {
       [Description("Gas")] 
       Gas,
       [Description("Fuel")]
       Fuel,
       [Description("Gas&Fuel")]
       GasFuel
   }

   ...


   var gasKeywords = Util.GetDescriptions<GasKeywords>();
   foreach(var r in records)
   {
        var found = gasKeywords.Contains(r);
        if (found)
        {

        }
   }

I'm not a generics master. If anyone has some ideas on how to get around the typing issues of the GetDescriptions() method that would be welcome. Unfortunately, I couldn't put a type constraint that expected Enum which makes this less than friendly to code around.

Matthew Cox
  • 13,566
  • 9
  • 54
  • 72
1

I've done something like this in my own project... edited for brevity...

USAGE: GetType(Operators).GetTitle(tName))

IMPLEMENTATION:

 <AttributeUsage(AttributeTargets.Field, AllowMultiple:=False, Inherited:=False)>
    Public Class EnumItemAttribute
        Inherits Attribute

        Public Property Title As String = String.Empty

        Public Property Description As String = String.Empty

    End Class

<Extension()>
    Public Function GetTitle(ByVal tEnum As Type, ByVal tItemName As String) As String

        Dim tFieldInfo As FieldInfo = Nothing

        tFieldInfo = tEnum.GetField(tItemName)
        For Each tAttribute As EnumItemAttribute In tFieldInfo.GetCustomAttributes(GetType(EnumItemAttribute), False)
            Return tAttribute.Title
        Next

        Return String.Empty

    End Function
Sam Axe
  • 33,313
  • 9
  • 55
  • 89
0

A C# identifier must start with an underscore, a character in the Unicode class Lu, Ll, Lt, Lm, Lo, or Nl, or an escape for one of those. All other characters must be from Unicode class Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc or Cf, or an escape for one of those.

An identifier can begin with @ but this is not part of the identifier but used to allow the same word as a keyword to be an identifier. Hence myVar and @myVar are the same identifier, while @if is a valid identifier while we couldn't use if because it would conflict with the keyword.

(§ 2.4.2 of the C# spec).

& is of class Po, and hence not covered by the rules.

For CLS-compliant identifiers, ECMA-335 requires identifiers to follow http://www.unicode.org/reports/tr15/tr15-18.html Annex 7, canonicalised to NFC, and without having names distinct by case alone, which is stricter still.

In short, you can't.

More to the point, why would you want to? How could you tell Gas&Fuel an identifier from Gas&Fuel an expression that has Gas and Fuel as operands to the & operator?

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251