比较两个枚举w/bitwise单个True结果?

edu*_*911 2 c# enums bit-manipulation bitwise-operators

如何比较具有多个位设置的枚举?我一定很遗憾.

我有一个枚举的目标持久值,我有相同枚举的用户设置.我需要比较两者以查看是否存在一个或多个枚举位的单个匹配.

额外奖励:我很乐意在这里使用按位运算符来快捷查询linq(因为我在不同的属性中复制了5到6次).我知道它不易读,但它确实有助于我正在做的事情.

public enum Targets
{
  NotSet = 0,

  Anonymous = 1,
  Everyone = 2
  Adult = 4,
  Child = 8,

  LikesFishing = 16
}
Run Code Online (Sandbox Code Playgroud)

我有多个目标设置的用户:

var loggedInUser = new User()
{
  Username = "eduncan911",
  Targets = Targets.Everyone | Targets.Adult | Targets.LikesFishing
};    
Run Code Online (Sandbox Code Playgroud)

我有多个不同目标的文章:

var article1 = new Article()
{
  Title = "Announcement for Parents and Children",
  Targets = Targets.Adult | Targets.Child
};

var article2 = new Article()
{
  Title = "What fishing boat do you own?",
  Targets = Targets.LikesFishing | Targets.Adult
};

var article3 = new Article()
{
  Title = "Be nice to your parents!",
  Targets = Targets.Child
};
Run Code Online (Sandbox Code Playgroud)

如何查询具有1个目标位集的文章,该目标位设置与上述指定用户的至少1个目标匹配(1个或更多)?我应该回到前两篇文章,因为它们匹配Targets.Adult - 但是loggedInUser.Targets与第3组目标中的任何位都不匹配.

我知道我可以查询特定枚举类型的文章,如下所示:

var articles =
  db.Articles.Where(x => x.Targets.HasFlag(Targets.LikesFishing);
Run Code Online (Sandbox Code Playgroud)

但是,我没有一个目标 - 我设置了多个位.因此,传入"loggedInUser.Targets"将永远不会匹配任何,因为存储的值只是一个int.

起初,我正在查询这样的枚举:

// returns a collection of enums the user has set
// in their profile.
var loggedInUserEnums =
  Enum.GetValues(typeof(Targets))
    .Cast<Targets>()
    .Where(x => loggedInUser.Targets.HasFlag(x));
Run Code Online (Sandbox Code Playgroud)

但是当将这个集合与其他文章集合的集合进行比较时,我总是对每篇文章都回归真实.我想我要去拉地了.

有没有按位操作我可以传入linq表达式db.Articles.Where(...)来比较这两个?

只是一个猜测,但我注意到当我查询文章目标时,我还有NotSet返回true - 无论我~Targets.NotSet与否.奇.

Cha*_*ana 6

如果你想看到目标是LikesFishing或Adult的文章,

试试这个:

 var target = Targets.LikesFishing | Targets.Adult;
 var articles =   db.Articles.Where(x => (int)(x.Targets & target) > 0 ); 
Run Code Online (Sandbox Code Playgroud)

哦,是的,添加[FlagsAttribute]到枚举:

[Flags]
public enum Targets 
{   NotSet = 0,  Anonymous = 1, Everyone = 2,
    Adult = 4,   Child = 8,    LikesFishing = 16 }
Run Code Online (Sandbox Code Playgroud)