C# 在C语言中模拟值类型多态性

C# 在C语言中模拟值类型多态性,c#,asp.net,C#,Asp.net,我正在寻找一种创建某种值类型层次类结构的方法。我知道枚举不支持继承,因为它们是值类型,因此是密封的,所以我可能正在寻找某种静态类实现 我这样做的目的是重新定义我正在处理的ASP.NET应用程序中的角色。目前,角色是字符串常量(ROLE_ADMIN、ROLE_USER等),并放在会话中,并在整个应用程序中进行检查,例如:Person.getRole()==ROLE_ADMIN(实际上是字符串比较)。我想重构它,这样我就可以有类型安全性,以及下面描述的某种多态行为 考虑以下角色结构:

我正在寻找一种创建某种值类型层次类结构的方法。我知道枚举不支持继承,因为它们是值类型,因此是密封的,所以我可能正在寻找某种静态类实现

我这样做的目的是重新定义我正在处理的ASP.NET应用程序中的角色。目前,角色是字符串常量(ROLE_ADMIN、ROLE_USER等),并放在会话中,并在整个应用程序中进行检查,例如:Person.getRole()==ROLE_ADMIN(实际上是字符串比较)。我想重构它,这样我就可以有类型安全性,以及下面描述的某种多态行为

考虑以下角色结构:

             user1
      Group1
             user2
Admin
      User3
如果一个人的角色设置为Group1,但页面上的某个元素仅由user1可见,那么我希望语句person.getRole()==user1为true

编辑:

将上述结构视为一棵树,我希望能够根据叶或节点定义用户,并根据叶或节点检查权限。然而,这就产生了一个难题,即根据节点检查权限是否检查用户属于组(group1)或组(Admin)。
我认为问题在于,将树的根节点命名为“Admin”会产生误导,因为节点本身应该被视为组,而不是角色。根节点应该类似于“All”,当它被定义为“All”时,将继承树的所有叶子,因此将属于所有组。

我猜用户必须登录吗?那么,当他们登录时,为什么不在会话中添加一个用户对象呢

// Object to represent a user
public class SiteUser
{
    public String Name { get; set; }
    public UserTypes UserType { get; set; }
}

// Enumeration of user types
public enum UserTypes : int
{
    Admin = 1,
    General = 2
}

public partial class Home : System.Web.UI.Page 
{    
    private void Login()
    {
        // Login method here, take username password etc...
        // This is for example purposes...
        SiteUser user = new SiteUser();

        user.UserType = UserTypes.Admin;
        user.Name = "Bob";

        Session["User"] = user;
    }
}

public partial class AdminOnlyPage : System.Web.UI.Page 
{    
    private void Page_Load(object sender, EventArgs e)
    {
        // On pages where we want to know the user details
        // cast the session user object back to our SiteUser object.
        SiteUser user = Session["User"] as SiteUser;

        // This page is admin only, if our user in session isn't an admin
        // then redirect them else where...
        if (user.UserType != UserTypes.Admin)
        {
            Response.Redirect("/LoginPage.aspx");
        }
    }
}

我不确定值类型与此有什么关系(字符串是引用类型)。这里常见的方法是使用或类似的方法


您的“层次”问题将转移到角色所在的部分

用对象模拟值类型语义的一种方法是不可变对象。如果这是一个不熟悉的概念,那么简短的版本是“在构造之后,它们不会改变状态”,即没有设置器,没有公共字段(但谁会以任何方式做这样愚蠢的事情;p)并且没有具有副作用的方法

Eric Lippert写了一系列关于不变性概念的文章:

我想我是在寻找不改变状态、只表示“值”的对象,所以我将其与值类型相关联。其他人也提到了不可变对象,我忘记了。我不知道.NET中内置的主体和标识结构,我将对此进行研究。此解决方案本身不实现类型安全,因此我必须研究包装主体/标识系统以使用枚举的选项。我知道有很多方法可以来回转换字符串和枚举。我还想以这样一种方式来包装它,即我不必执行诸如Principal.IsInRole('user1')| | Principal.IsInRole('user2')之类的检查来确定它们是否在组1中。用法更像
currentPrinicpal.IsInRole('group1')
抱歉,我没有指定,用户不必登录,有一个web服务可以传递凭据,应用程序将该状态放入会话中。该解决方案通过使用枚举解决了类型安全问题,但层次结构问题仍未解决。我不想将ADMIN定义为它自己的角色,而是其他角色的集合。参考我的示例,我只会针对树中的叶子角色签入代码,而树中的节点将根据它们的子树中叶子所包含的角色而被允许。我已经忘记了不可变对象。我将进一步调查此事。我将减少损失,暂时放弃这个问题。为了将来的参考,我已经标出了我认为最合适的答案。不幸的是,这一变化没有任何商业原因,而且开始需要太多时间才能完成。