【问题标题】:Getting Enum type from string of chars从字符串中获取枚举类型
【发布时间】:2015-06-08 16:40:50
【问题描述】:

我看过类似的问题,但他们似乎没有处理我遇到的相同问题。

我有一个定义为 CRUD 权限测试的枚举

public enum CRUDOperation
    {
        NotNeeded = 0,
        Read = 1,
        Create = 2,
        Update = 4,
        Delete = 8
    }

我没有编写下一部分代码,这就是为什么我可能会感到困惑的原因,但是随后将与角色关联的 CRUD 权限值以下列方式放入“限制”字符串中。

            Restrictions = "";
            foreach (string inCrud in restrictions)
            {
                string crud = inCrud.ToUpper();
                int res = 0;
                if (crud.Contains('C'))
                    res |= (char)CRUDOperation.Create;
                if (crud.Contains('R'))
                    res |= (char)CRUDOperation.Read;
                if (crud.Contains('U'))
                    res |= (char)CRUDOperation.Update;
                if (crud.Contains('D'))
                    res |= (char)CRUDOperation.Delete;
                Restrictions += (char)res;
            }

现在我需要解析这个“限制”字符串来检查给定角色是否具有适当的 CRUDOperation 权限级别。然而,字符串中充满了随机的 ascii 字符,我只是很难理解如何正确地做到这一点。我以前根本没有使用过位掩码。我正在尝试这样做;

CRUDOperation operation = (CRUDOperation)Enum.Parse(typeof(CRUDOperation), p.Restrictions);

但我收到错误“未找到请求的值''。”

有人有什么建议吗?

【问题讨论】:

  • 这似乎是一种非常简单的方法,非常令人困惑。
  • 我不确定第二段代码是否符合原作者认为的功能。使用Flags 属性会容易得多...
  • 那么它到底在做什么呢?我对正在发生的事情的印象是将枚举值添加到限制字符串中的 0 或字符转换?
  • 当您将枚举值转换为 char 时,您会从 ASCII 表中获取 char 0(不可打印字符),而不是表示 0 的字符,即 ASCII 表中的 48。而且,我同意@Icemanind,这段代码过于复杂。
  • 我不确定我是否会称写这篇文章的人为“更好的编码器”。

标签: c# string enums enumeration


【解决方案1】:

您在该代码中的问题是,当您这样做时:Restrictions += (char)res; 您实际上是在添加其代码是您的操作结果的字符。生成的 Restrictions 字符串无法解析为枚举。

我不确定为什么 Restrictions 保留为字符串。我会将 Restrictions 的类型更改为 CRUDOperation 并用以下代码替换第一位代码:

 Restrictions = CRUDOperation.None;
 foreach (string inCrud in restrictions)
 {
     string crud = inCrud.ToUpper();
     int res = 0;
     if (crud.Contains('C'))
        Restrictions |= CRUDOperation.Create;
     if (crud.Contains('R'))
        Restrictions |= CRUDOperation.Read;
     if (crud.Contains('U'))
        Restrictions |= CRUDOperation.Update;
     if (crud.Contains('D'))
        Restrictions |= CRUDOperation.Delete;
 }

这样你就可以直接得到结果了。

如果由于某种原因您必须有一个带有结果的字符串,您需要为要添加的值使用分隔符:Restrictions += " " + (int)res; 之后,您可以通过拆分字符串然后解析它来解析它(确保在解析之前删除所有空条目)。

【讨论】:

    【解决方案2】:

    在回答这个问题之前,我只想指出这是一种糟糕的做事方式。但我假设您继承了代码并且您无法更改它。但请记住,代码不应该这样工作。更好的方法是将其存储在List<CRUDOperation> 中,而不是将其全部连接到一个字符串中。

    好的,现在回答您。据我所知,这段代码似乎在做的是建立一个enum 值的字符串。所以如果代码看起来像这样:

    String Restrictions = "";
    string[] restrictions = {"U", "C", "R"};
    
    foreach (string inCrud in restrictions)
    {
        string crud = inCrud.ToUpper();
        int res = 0;
        if (crud.Contains('C'))
            res |= (char)CRUDOperation.Create;
        if (crud.Contains('R'))
            res |= (char)CRUDOperation.Read;
        if (crud.Contains('U'))
            res |= (char)CRUDOperation.Update;
        if (crud.Contains('D'))
            res |= (char)CRUDOperation.Delete;
        Restrictions += (char)res;
    }
    

    这将构建一个包含以下内容的不可读字符的字符串:

    0x04, 0x02, 0x01
    

    因此,如果您需要根据此字符串确定某人是否具有权限,您可以执行以下操作:

    bool hasReadPermission = HasCrudPermission(Restrictions, CRUDOperation.Read);
    bool hasCreatePermission = HasCrudPermission(Restrictions, CRUDOperation.Create);
    bool hasUpdatePermission = HasCrudPermission(Restrictions, CRUDOperation.Update);
    bool hasDeletePermission = HasCrudPermission(Restrictions, CRUDOperation.Delete);
    
        private bool HasCrudPermission(string restrictions, CRUDOperation permission)
        {
           return restrictions.Any(c => HasCrudPermission(c, permission));
        }
    
        private bool HasCrudPermission(char restriction, CRUDOperation permission)
        {
            return ((CRUDOperation)restriction) == permission;
        }
    

    【讨论】:

    • 感谢您的回复。这似乎是最有意义的,所以我尝试实现它,但由于某种原因,它只是返回 false 除了“读取”之外的所有内容,无论如何。不知道为什么。
    • restrictions 的结构是否像我所拥有的那样:string[] restrictions = {"U", "C", "R"};
    猜你喜欢
    • 2018-11-25
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多