"&" в перечислении? - PullRequest
       2

"&" в перечислении?

1 голос
/ 12 января 2012

Я хочу использовать некоторые файлы, и мне нужно знать, куда поместить каждую из данных. Один столбец называется «Категория».

У меня может быть много категорий, и я хочу создать перечисление для их поддержки.

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

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

Я думаю о чем-то подобном

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

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

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

и продолжайте использовать TryParse до тех пор, пока я не найду группу, которую она тоже сможет анализировать. Я не уверен, что это лучший способ сделать это (я всегда открыт для лучших идей).

Однако проблема, с которой я сейчас сталкиваюсь, заключается в том, что я не могу использовать «&» в именах перечислений. У меня нет контроля над этими именами категорий, поэтому я не могу их изменить.

Ответы [ 3 ]

4 голосов
/ 12 января 2012

Почему бы не использовать тег Description, чтобы обойти эту проблему. Конечно, это не совсем то, для чего он был разработан, но если вы не согласны с этим, вы всегда можете придумать свой собственный класс атрибутов.

Вот быстрый грязный метод, который я написал для получения атрибута описания объекта

    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();
    }

Вот быстрый грязный служебный метод для получения списка всех дескрипторов объекта в виде списка

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;
}

Теперь, чтобы использовать их для нужного вам эффекта

   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)
        {

        }
   }

Я не мастер дженериков. Если у кого-то есть идеи о том, как обойти проблемы с типизацией метода GetDescription (), это будет приветствоваться. К сожалению, я не смог установить ограничение типа, которое ожидало бы Enum, что делает это менее удобным для кода.

1 голос
/ 12 января 2012

Я сделал что-то подобное в своем собственном проекте ... отредактировано для краткости ...

ИСПОЛЬЗОВАНИЕ: GetType(Operators).GetTitle(tName))

РЕАЛИЗАЦИЯ:

 <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
0 голосов
/ 12 января 2012

Идентификатор AC # должен начинаться с подчеркивания, символа в классе Unicode Lu, Ll, Lt, Lm, Lo или Nl или с экранирования для одного из них.Все остальные символы должны быть из класса Unicode Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc или Cf, или же для одного из них должен быть экранированный символ.

Идентификатор может начинаться с @но это не часть идентификатора, но используется для того, чтобы идентификатором могло быть то же слово, что и в ключевом слове.Следовательно, myVar и @myVar являются одним и тем же идентификатором, в то время как @if является действительным идентификатором, в то время как мы не можем использовать if, потому что это будет конфликтовать с ключевым словом.

(§ 2.4.2спецификация C #).

& относится к классу Po и, следовательно, не охватывается правилами.

Для CLS-совместимых идентификаторов ECMA-335 требует, чтобы идентификаторы следовали за http://www.unicode.org/reports/tr15/tr15-18.html Приложение 7, канонизированное для NFC и не имеющее имен, различающихся только по регистру, что еще более строгое.

Короче говоря, вы не можете.

Более конкретно, почемуты хочешь?Как вы могли бы сказать Gas&Fuel идентификатор из Gas&Fuel выражения, у которого Gas и Fuel являются операндами для оператора &?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...