2016-08-25 6 views
4

В C# я сохраняю значение перечисления флагов в базе данных в виде байта. Например, для следующих флагов перечисления:C# - как проверить, совпадает ли значение байта с любыми флагами в указанном флажке перечисления?

[Flags] 
public enum Options 
{ 
    None = 0, 
    First = 1, 
    Second = 2, 
    Third = 4 
} 

Если я хочу, чтобы записать «Первый» и «Второй», я сохраняю это как байты «3» в поле «Параметры» в записи в база данных.

Так при использовании LINQ, как я могу проверить, если значение в базе данных соответствует «любой» из вариантов в качестве аргумента, переданного в качестве перечисления «Options», что-то вроде этого псевдокода:

public static Something(Options optionsToMatch) 
    { 
     db.MyEntity.Get(a => a.options contains any of the options in optionsToMatch); 
+0

Почему это downvoted? –

+0

Не «имеет какой-либо вариант» так же, как «не имеет« ничего »? – Sehnsucht

+0

Нет, я имею в виду, что если байт (a.options) представляет любой из параметров, переданных в 'optionsToMatch', тогда это должно быть совпадение –

ответ

1

Вот код, который делает то, что вы хотите, итерируя по перечислениям (я взял этот ответ от here).

static void Main() 
    { 
     //stand-in for my database 
     var options = new byte[] { 1, 2, 3, 3, 2, 2, 3, 4, 2, 2, 1,5 }; 

     var input = (Options)5; 

     //input broken down into a list of individual flags 
     var optional = GetFlags(input).ToList(); 
     //get just the options that match either of the flags (but not the combo flags, see below) 
     var foundOptions = options.Where(x => optional.Contains((Options)x)).ToList(); 
     //foundOptions will have 3 options: 1,4,1 
    } 

    static IEnumerable<Enum> GetFlags(Enum input) 
    { 
     foreach (Enum value in Enum.GetValues(input.GetType())) 
      if (input.HasFlag(value)) 
       yield return value; 
    } 

EDIT

Если вы хотите, чтобы найти 5 в этом примере (поле со списком опций), просто добавить дополнительные или состояние так:

var foundOptions = options.Where(x => optional.Contains((Options)x) || input == (Options)x).ToList(); 
0

Во-первых, определить флаги полезны. Один бит для каждого флага, так что их можно легко комбинировать в любой комбинации.

[Flags] 
enum opts : byte { 
    A = 1 << 0, 
    B = 1 << 1, 
    C = 1 << 2, 
    D = 1 << 3, 
    //.. etc 
} 

Тогда просто побитовое И и посмотреть, если это не равно 0

opts a = opts.A | opts.D; 
opts b = opts.B | opts.C | opts.D; 
var c = a & b; //D 

if((byte)c!=0){ 
    // ... things 
} 
+0

Прежде всего, он уже определил флаги «полезно», выполнив именно то, что вы сделали. Преобразуйте свои предпочтения в байт, и вы заметите, что они 1,2,4,8. Единственное, что добавляет ваш метод, - это дополнительный умственный контроль для всех последующих разработчиков относительно того, что такое 2^3. Это также делает код громоздким, потому что если «opts b» - это список из базы данных с несколькими сотнями результатов, вы предлагаете, чтобы код повторялся и побитовым, или все из них, просто чтобы сравнить их с другим поразрядным или? Весь смысл флагов заключается в том, что побитовое или уже сделано для вас. – Kolichikov

+0

Да, так они и есть, я думаю, что я неправильно понял 3 вместо 4. Мой плохой. – moreON

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

  • Нет связанных вопросов^_^