如何正确隐藏基类属性

发布于 2024-11-15 22:06:22 字数 903 浏览 2 评论 0原文

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

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." );
        }
    }

There is a base class (black box; can't modify it) that I derive from. In my derived class, I no longer want to allow users to use a property, instead I have a public function now to use instead. I won't go into the details of why (it is irrelevant), but here is the property I'm trying to hide:

public ComboBoxItemCollection Items { get; }

I've tried this, but it didn't work:

private new ComboBoxItemCollection Items { get; set; }

I also tried this, however the compiler says I am not allowed to make both accessors private:

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

How do I properly accomplish this? Note that I'm not depending on this being a complete security solution, obviously through means of casting to the base class they can still call this property. This is simply meant to offer the user a compile-time error, which helps guide them to realize they cannot use this property and instead should use the new function in the derived class.

EDIT

Thanks to the answers in this thread, I came up with the following solution:

    [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." );
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

秋叶绚丽 2024-11-22 22:06:22

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

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

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

You can't. The closest you could come would be:

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

Personally I'd be tempted to ask whether you should really be deriving from this if you don't want all the members though... can you use composition instead?

骄傲 2024-11-22 22:06:22

即使可能,您也不想“隐藏”访问器(正如您所指出的,它们只能通过基类访问)。您遇到警告/错误,提示“此方法已弃用,应该避免”。因此,您可能需要查看 Obsolete 属性,记录为“属性 Obsolete 用于标记不应再使用的类型和类型成员” - 正是您的用例。

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

Even if it were possible, you don't really want to "hide" the accessors (as you've noted, they can just be accessed through the base class). You're after a warning/error that says "This method is deprecated, and should be avoided". As such, you might want to look at the Obsolete attribute, documented as "The attribute Obsolete is used to mark types and members of types that should no longer be used" - exactly your use case.

Edit: I strongly advise against throwing an exception in the accessor. This would violate what's commonly called the "Liskov substitution principle" - that you can use a derived class anywhere that a base class is desired. Really, that's just fancy language around the fact that existing code that you might pass a derived instance into is expecting a .Items getter that functions in a sensible fashion, rather than exploding on contact. If you throw an exception, you might get hard to debug errors in very hard to reach places (given that your superclass is a black box).

牛↙奶布丁 2024-11-22 22:06:22

您可以在子类中将该属性设为公共,并在访问该属性时抛出异常。然后,您必须确保仅访问子类中的基类属性。

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

You could make the property public in the child class and throw an Exception if it is accessed. You have to make sure then that you only access the base class property within the child class.

public new ComboBoxItemCollection Items
{
    get { throw new InvalidOperationException(); }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文