【问题标题】:How to properly hide a base class property如何正确隐藏基类属性
【发布时间】:2011-06-16 16:09:46
【问题描述】:

我从中派生了一个基类(黑盒;不能修改它)。在我的派生类中,我不再希望允许用户使用属性,而是现在有一个公共函数可供使用。我不会详细说明原因(无关紧要),但这是我试图隐藏的属性:

public ComboBoxItemCollection Items { get; }

我试过了,但是没用:

private new ComboBoxItemCollection Items { get; set; }

我也试过这个,但是编译器说我不允许将两个访问器都设为私有:

public new ComboBoxItemCollection Items { private get; private set; }

我该如何正确地做到这一点?请注意,我并不依赖于这是一个完整的安全解决方案,显然通过转换为基类他们仍然可以调用此属性。这只是为了给用户一个编译时错误,这有助于引导他们意识到他们不能使用这个属性,而应该使用派生类中的新函数。

编辑

感谢这个帖子中的答案,我想出了以下解决方案:

    [Obsolete( "This property is obsolete. Please use MRUIdComboBox.AddItem() instead.", true )]
    public new ComboBoxItemCollection Items
    {
        get
        {
            throw new NotSupportedException( "This property is not supported. Please use MRUIdComboBox.AddItem() instead." );
        }
    }

【问题讨论】:

    标签: c# method-hiding


    【解决方案1】:

    你不能。您最接近的可能是:

    [Obsolete(IsError=true)]
    public new ComboBoxItemCollection Items
    {
        get { return base.Items; } // Or throw an exception
    }
    

    我个人很想问,如果你不想要所有成员,你是否真的应该从这个派生......你可以使用组合来代替吗?

    【讨论】:

      【解决方案2】:

      即使有可能,您也不想“隐藏”访问器(正如您所指出的,它们只能通过基类访问)。您遇到了一个警告/错误,上面写着“此方法已弃用,应避免使用”。因此,您可能想查看Obsolete attribute,记录为“属性已过时用于标记不应再使用的类型和类型的成员”——这正是您的用例。

      编辑:我强烈建议不要在访问器中抛出异常。这将违反通常所说的“Liskov 替换原则”——您可以在需要基类的任何地方使用派生类。确实,这只是一种花哨的语言,即您可能将派生实例传递到其中的现有代码期望.Items getter 以合理的方式运行,而不是在接触时爆炸。如果你抛出一个异常,你可能很难在很难到达的地方调试错误(假设你的超类是一个黑盒子)。

      【讨论】:

        【解决方案3】:

        您可以在子类中公开该属性,并在访问时抛出异常。您必须确保您只能访问子类中的基类属性。

        public new ComboBoxItemCollection Items
        {
            get { throw new InvalidOperationException(); }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-01
          • 2021-02-27
          • 1970-01-01
          • 2015-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多