2016-08-25 51 views
4

在C#中,我將標記枚舉值作爲字節存儲在數據庫中。例如,對於下面的標誌枚舉:C# - 如何檢查字節值是否與指定標誌枚舉中的任何標誌匹配?

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

如果我想記錄「第一」和「二」,我這個在「選項」中的一個記錄的字段保存爲「3」字節數據庫。

因此,在使用LINQ的時候,我怎麼能檢查是否在數據庫中的值相匹配的爲「選項」枚舉傳遞參數,像這樣的僞代碼選項「任何」:

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

編輯

如果你也想找到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'是來自數據庫的具有幾百個結果的列表,那麼您是否建議代碼迭代並按位或全部進行比較,只是爲了將它們與另一個按位進行比較呢? Flags的全部重點在於按位或已經爲您完成。 – Kolichikov

+0

呵呵,所以他們是,我想我誤讀了3,而不是4。 – moreON