【问题标题】:C# - how do I check if a byte value matches against any flags in a specified flags enum?C# - 如何检查字节值是否与指定标志枚举中的任何标志匹配?
【发布时间】:2016-08-25 01:05:28
【问题描述】:

在 C# 中,我将标志枚举值作为字节存储在数据库中。例如,对于以下 Flags 枚举:

[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);

【问题讨论】:

  • 为什么这被否决了?
  • “有任何选项”与“没有None”不一样吗?
  • 不,我的意思是如果字节(a.options)代表'optionsToMatch'中传递的任何选项,那么它应该是一个匹配
  • 这仍然完全不清楚(至少对我来说);任何值(可能是负值除外)表示一个选项或选项的组合,因此是一个匹配项

标签: c# enums flags


【解决方案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();

【讨论】:

    【解决方案2】:

    首先,有用地定义标志。每个标志都有一个单独的设置位,因此它们可以很容易地组合成任何组合。

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

    然后按位 AND 看看它是否不等于 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
    }
    

    【讨论】:

    • 首先,他已经定义了“有用”的标志,完全按照您所做的。将您的选择转换为字节,您会注意到它们是 1、2、4、8。您的方法添加的唯一一件事是对所有后续开发人员进行额外的心理检查,以了解 2^3 是什么。这也使代码变得繁琐,因为如果“opts b”是来自数据库的具有几百个结果的列表,那么您是建议代码迭代和按位还是全部,只是为了将它们与另一个按位进行比较? Flags 的全部意义在于按位或已经为您完成。
    • 嗯,原来如此,我想我误读了 3 而不是 4。我的错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多