Pergunta

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." );
        }
    }
Foi útil?

Solução

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?

Outras dicas

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).

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(); }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top