2010-09-07 6 views
4

Я хотел бы ограничить использование пользователем любого из enumvalue. Если пользователь пытается присвоить более двух значений, я должен выбросить ошибку.Как проверить, назначена ли переменная перечисления с единственным значением перечисления?

public enum Fruits 
{ 
    Apple, 
    Orange, 
    Grapes 
} 

public Fruits Fruits 
{ 
    get 
    { 
     return m_fruits; 
    } 
    set 
    { 
     m_fruits=value; 
    } 
} 

Fruits = Fruits.Apple & Fruits.Grapes; //I need to avoid such type of assignment 

Может ли кто-нибудь сказать, как проверить этот тип проверки.

Спасибо, Lokesh

+3

Ничего технического, но НЕ используя множественное число, а называющие свойства помогают других разработчиков, что он не предназначен для использования в качестве битовых флагов. – Hemant

ответ

9

Вы можете использовать Enum.IsDefined, чтобы узнать, действительно ли определено интегральное значение для перечисления. Чтобы иметь возможность обнаружить, что не использовалась логическая операция, такая как Fruits.Apple | Fruits.Grapes, убедитесь, что ваши значения перечисления являются флагами.

public enum Fruits 
{ 
    Apple = 1, 
    Orange = 2, 
    Grapes = 4 
} 

public Fruits Fruit 
{ 
    get 
    { 
     return m_fruits; 
    } 
    set 
    { 
     if (!Enum.IsDefined(typeof(Fruits), value)) 
     { 
      throw new ArgumentException(); 
     } 
     m_fruits = value; 
    } 
} 

Update:

Более быстрый метод без отражения будет проверить все значения перечисления себя:

public Fruits Fruit 
{ 
    get 
    { 
     return m_fruits; 
    } 
    set 
    { 
     switch (value) 
     { 
      case Fruits.Apple: 
      case Fruits.Grapes: 
      case Fruits.Orange: 
       m_fruits = value; 
       break; 
      default: 
       throw new ArgumentException(); 
     } 
    } 
} 
+0

Мне это не нравится. 'IsDefined' включает отражение жира, и оно медленное. Это действительно проще использовать класс типа «Кодировки», где есть статические поля с экземплярами. – Andrey

+0

@Andrey: Правда, что 'IsDefined' использует отражение и не самый быстрый. При использовании перечисления единственный другой метод, который у вас есть, - это явно проверить все определенные значения, например. используя оператор 'switch'. –

1

То есть операция поразрядного, и может быть использован только в сочетании с атрибутом [Flags], и когда вы значения для вашего перечислений явно применимы к флагам (например, 1, 2, 4, 8, 16 и т.д.)

+0

IIRC атрибут [Flags] предназначен только для диагностики (BTW, я не рекомендую его исключать). –

+0

@Richard -> Спасибо, я попытался добавить такие thisngs.If пользователь использовал '| 'вместо' & ', тогда значение будет возвращено, например, будет 6 (например), которые приводят к раздражающим результатам. – Lokesh

+0

Нет, что вам нужно сделать, это не атрибут '[Flags]', и тогда вы должны быть в порядке, потому что, как сказал Фредрик, если его не отмечен атрибутом '[Flags]', тогда любая побитовая операция будет return 0. –

5

Вы можете использовать метод Enum.IsDefined(), чтобы проверить, является ли значение допустимым значением перечисления:

Fruits f1 = Fruits.Orange; 
Fruits f2 = (Fruits)77; 

var b1 = Enum.IsDefined(typeof(Fruits), f1); // => true 
var b2 = Enum.IsDefined(typeof(Fruits), f2); // => false 

BTW: Ваш пример кажется неправильным: var f = Fruits.Apple&Fruits.Grapes назначит Fruits.Apple - f. Это связано с тем, что побитовое И из Apple (== 0) и Grapes (== 2) приведет к 0 (что все еще является допустимым значением перечисления -> Apple).

Если вы имели в виду что-то вроде var f = Fruits.Orange|Fruits.Grapes, то е теперь будет (побитовое ИЛИ 1 и 2) и Enum.IsDefined теперь будет возвращать ложь.

0

Вы не можете ограничить его. Единственный способ сделать это для создания пользовательского класса и создания статических полей с экземплярами (например, Encoding). Кстати, побитовое & бессмысленно для enum, которое не помечено как [Flags]. Fruits.Apple&Fruits.Grapes не будет устанавливать два значения (| делает), он будет производить бессмысленный результат: так как по умолчанию перечислений преобразуются в последовательность целых чисел Fruits.Apple&Fruits.Grapes будет производить Fruits.Apple потому Apple сопоставляется 0

Смежные вопросы