【问题标题】:How to increase the access modifier of a property如何增加属性的访问修饰符
【发布时间】:2010-10-27 13:59:51
【问题描述】:

我正在尝试创建一组类,其中一个共同的祖先负责设置各种属性所涉及的所有逻辑,而后代只是根据特定后代中是否需要它们来更改属性的访问权限。

当我尝试如下所示执行此操作时,我得到一个编译器错误:“覆盖'受保护'继承成员时无法更改访问修饰符”

有没有办法实现我想要做的事情?谢谢

public class Parent
{
     private int _propertyOne;
     private int _propertyTwo;

     protected virtual int PropertyOne
     {
          get { return _propertyOne; }
          set { _propertyOne = value; }
     }

     protected virtual int PropertyTwo
     {
          get { return _propertyTwo; }
          set { _propertyTwo = value; }
     }
}

public class ChildOne : Parent
{
    public override int PropertyOne  // Compiler Error CS0507
    {
        get { return base.PropertyOne; }
        set { base.PropertyOne = value; }
    }
    // PropertyTwo is not available to users of ChildOne
}

public class ChildTwo : Parent
{
    // PropertyOne is not available to users of ChildTwo
    public override int PropertyTwo  // Compiler Error CS0507
    {
        get { return base.PropertyTwo; }
        set { base.PropertyTwo = value; }
    }
}

【问题讨论】:

    标签: c# oop polymorphism


    【解决方案1】:

    您可以通过使用“new”而不是“override”来隐藏父级的受保护属性,如下所示:

    public class ChildOne : Parent
    {
        public new int PropertyOne  // No Compiler Error
        {
            get { return base.PropertyOne; }
            set { base.PropertyOne = value; }
        }
        // PropertyTwo is not available to users of ChildOne
    }
    
    public class ChildTwo : Parent
    {
        // PropertyOne is not available to users of ChildTwo
        public new int PropertyTwo
        {
            get { return base.PropertyTwo; }
            set { base.PropertyTwo = value; }
        }
    }
    

    【讨论】:

    • OOPS .. 快几秒 :) .. 无论如何,使用 new 与覆盖不同; new 隐藏了父成员,这样它就不再是多态了。
    【解决方案2】:

    没有。您仍然可以使用 Your's 隐藏继承的属性

    public class ChildTwo: Praent { 
        public new int PropertyTwo { 
           // do whatever you want
        }
    }
    

    ps:这不再是虚拟/覆盖关系(即没有多态调用)

    【讨论】:

    • @7alwagy,谢谢。在我的情况下,虚拟/覆盖无关紧要,我只是认为我需要它来覆盖基本属性。使用“新”而不是“覆盖”就可以了。
    【解决方案3】:

    您无法更改访问权限,但您可以重新声明具有更大访问权限的成员:

    public new int PropertyOne
    {
        get { return base.PropertyOne; }
        set { base.PropertyOne = value; }
    }
    

    问题在于这是一个不同 PropertyOne,继承/虚拟可能无法按预期工作。在上述情况下(我们只是调用base.*,并且新方法不是虚拟的)这可能没问题。如果你需要真正的多态性以上,那么你不能在不引入中间类的情况下做到(AFAIK)(因为你不能new和override同类型的同一个成员):

    public abstract class ChildOneAnnoying : Parent {
        protected virtual int PropertyOneImpl {
            get { return base.PropertyOne; }
            set { base.PropertyOne = value; }
        }
        protected override int PropertyOne {
            get { return PropertyOneImpl; }
            set { PropertyOneImpl = value; }
        }
    }
    public class ChildOne : ChildOneAnnoying {
        public new int PropertyOne {
            get { return PropertyOneImpl; }
            set { PropertyOneImpl = value; }
        }
    }
    

    上面的重点是仍然有一个虚拟成员需要覆盖:PropertyOneImpl。

    【讨论】:

    • @Marc,我可能很困惑,因为我认为我需要虚拟/覆盖,但显然在这种情况下我不需要。当我确实需要使用多态性时,我会保留一个指向您的答案的链接:) 感谢您的解释和示例代码。
    猜你喜欢
    • 2013-03-09
    • 2015-08-14
    • 2014-03-06
    • 2012-11-22
    • 2013-09-18
    • 2017-06-13
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    相关资源
    最近更新 更多