C#继承中的访问修饰符

4

我想要多个版本的对象,这些对象的属性有不同的访问修饰符。

例如,我可能有一个用户类 -

public abstract class UserInfo
{
    internal UserInfo()
    {
    }
    public virtual int ID { get; set; }
    public virtual string Password { internal get; set; }
    public virtual string Username { get; set; }
}

public class ReadUserInfo : UserInfo 
{
    internal ReadUserInfo()
    {
    }
    override public int ID { get; internal set; }
    override internal string Password { get; set; }
    override public string Username { get; internal set; }
}

public class NewUserInfo : UserInfo
{
    internal NewUserInfo()
    {
        ID = -1;
    }
     //You get the Idea
}

这是我可以实现的东西吗?还是我必须以更编程化的方式控制访问?


1
我应该提到,上面的代码会导致“无法更改覆盖'pubic'继承成员时的访问修饰符...”错误。 - Kelly Robins
你想要实现什么目标?你是在寻求设计帮助,还是只是好奇这个方案是否可行? - Nader Shirazie
2
我必须同意Nader的观点。在基类中声明一个公共属性,然后在派生类中隐藏它只会导致问题。我会寻找解决问题的新方法。也许实现某些类而不是其他类的接口可以解决您的问题。 - ScottS
回顾我的旧问题,现在看到这个问题感到非常尴尬 - 哦,无论如何,至少其他人可能会发现这很有用。 - Kelly Robins
2个回答

14

继承真的适合这里吗?UserInfo类的用户不应该知道其子类型。在这种情况下,用户需要知道当使用ReadUserInfo实例而不是UserInfo实例时,Password属性不可用。

这真的没有意义。

编辑:在面向对象设计中,这被称为里氏替换原则


这是一半实验性重写,一半个人项目的学习练习。我不太确定自己是否朝着正确的方向前进。当存回基本类型时,我的行为也有误。所以,这个想法很糟糕。感谢您的建议! - Kelly Robins

4

你可以使用new修饰符:

public class ReadUserInfo : UserInfo
{
    internal ReadUserInfo()
    {
    }
    new public int ID { get; internal set; }
    new internal string Password { get; set; }
    new public string Username { get; internal set; }
}

我测试了一下,实际上根本不起作用。基类中的“Password”属性仍然在其他程序集中可见。 - Nader Shirazie
当您从基类继承时,您正在创建一个新类,而不是修改基类的行为。当然,UserInfo的“Password”属性仍然在程序集外可见,但ReadUserInfo.Password则不可见。 - manji
@najmeddine:没错,这意味着如果你在程序集内正确(或错误地)进行转换,你将得到UserInfo.Password或ReadUserInfo.Password。这就是这种方法的问题所在。 - Nader Shirazie
不幸的是,这是面向对象编程中抽象模型开始崩溃的地方之一。最好完全避免这种情况,以避免让使用该类的人感到困惑。 - Nate C-K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接