【问题标题】:Typed enum-like representation of table表的类型化枚举表示
【发布时间】:2016-08-23 10:02:44
【问题描述】:

我有一个“Aspnet_Role”表,其中包含“Admin”、“Moderator”等字符串值。我希望这些值有一个类似枚举的表示形式(手动更新),但是像这样放置一个实际的枚举课堂内:

public enum Role
{
    None, Admin, Moderator
}

导致一个尴尬的使用约定:Aspnet_Role.Role.Admin。我宁愿能够做到:Aspnet_Role.Admin

我想到了类似字符串属性的东西:

public static string Admin { get { return "Admin"; } }

但是我失去了枚举的强类型优势。例如,使用枚举我可以创建一个很好的辅助方法,例如:

public static bool IsUserInRole(Aspnet_Role.Role role){
    return System.Web.HttpContext.Current.User.IsInRole(role.ToString());
}

有没有办法在没有Aspnet_Role.Role 命名和用法的情况下创建表中值的强类型(即无字符串)枚举?

如果每个值只在代码中出现一次,那将是非常可取的。仅使用枚举,就是这种情况。使用字符串属性,每个值将是两次。使用枚举 AND 属性,例如:

public static Role Admin { get { return Role.Admin; 

每个值将是三倍!不漂亮。哦,请不要建议Reflection。我知道你想。

【问题讨论】:

标签: c# asp.net enums


【解决方案1】:

起初 - 我会将角色存储在数据库中作为 integer,而不是 string

但如果你坚持使用字符串值,请像这样创建属性:

public Role UserRole { get; set; }

您可以从数据库中加载它并以这种方式将其分配给属性:

string role = // load it here from db
this.UserRole = (Role)Enum.Parse(typeof(Role), role);

但仍将其存储为int 是更好的选择。

编辑:

如果您按照我的建议使用int,则分配给该属性将是:

int role = // load it here from db
this.UserRole = (Role)Enum.ToObject(typeof(Role), role);

【讨论】:

  • 我认为您错过了问题的重点,操作员希望避免写AspNet_Role.Role...。您的解决方案无法解决此问题。
  • 您的代码中的RoleUserRole 是什么?我只有Aspnet_Role。至于整数,这是一个遗留系统;我不想改变太多,只要确保新代码比以前的代码更好。
  • 好吧,如果我理解 id 是对的,就这样做吧:public static Role Admin { get { return Role.Admin; } } 但我不明白这一点..
  • 角色是你的枚举:public enum Role { None, Admin, Moderator }
  • 因为Role 必须在一个类型中,不是吗?所以应该是Aspnet_role.Role.Admin。这就是问题的重点!
【解决方案2】:

只是类型安全枚举的一个例子:

public class Aspnet_Role
{
    public static readonly Aspnet_Role None = new Aspnet_Role(Roles.None, "None");
    public static readonly Aspnet_Role Admin = new Aspnet_Role(Roles.Admin, "Admin");
    public static readonly Aspnet_Role Moderator = new Aspnet_Role(Roles.Moderator, "Moderator");

    private Aspnet_Role(Roles role, string name)
    {
        Role = role;
        Name = name;
    }

    public enum Roles
    {
        None,
        Admin,
        Moderator
    }

    public Roles Role { get; private set; }
    public string Name { get; private set; }

    public Aspnet_Role Parse(Roles role)
    {
        switch(role)
        {
            case Roles.Moderator:
                return Moderator;
            case Roles.Admin:
                return Admin;
            case Roles.None:
            default:
                return None;
        }
    }

    public bool IsUserInRole(Aspnet_Role role)
    {
        return Role == role.Role;
    }

    public override bool Equals(object obj)
    {
        if (obj is Aspnet_Role)
        {
            return Role == ((Aspnet_Role)obj).Role;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public override string ToString()
    {
        return Name;
    }
}

【讨论】:

  • 这是一种有趣的方法,但我真的不喜欢每个可能的值必须在代码中声明 五次 次。我怀疑使用的美感会与代码审查中样板的丑陋程度相提并论……
  • 是的,这太过分了。我通常将它用作原始枚举的扩展,您只能使用整数作为值。
【解决方案3】:

根据 ConnersFan 的评论,您可以在与 Aspnet_Role 类相同的命名空间中声明枚举,并根据需要使用它:

namespace DataLayer
{
    public enum Role
    {
        None,
        Admin,
        Etc
    };

    public partial class Aspnet_Role { }
}

如果能以某种方式表明该枚举以某种方式对应于 Aspnet_role 类,那就太好了。也许通过属性?

[Represents(Aspnet_Role)]
public enum Role { … }

我不知道。也许评论会更好。

【讨论】:

    猜你喜欢
    • 2011-04-15
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多