Как правильно скрыть свойство базового класса - PullRequest
4 голосов
/ 16 июня 2011

Существует базовый класс (черный ящик; я не могу его изменить), из которого я наследую. В моем производном классе я больше не хочу разрешать пользователям использовать свойство, вместо этого у меня есть публичная функция, которую можно использовать вместо этого. Я не буду вдаваться в детали того, почему (это не имеет значения), но вот свойство, которое я пытаюсь скрыть:

public ComboBoxItemCollection Items { get; }

Я пробовал это, но это не сработало:

private new ComboBoxItemCollection Items { get; set; }

Я также попробовал это, однако компилятор говорит, что мне не разрешено делать оба средства доступа закрытыми:

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

Как мне правильно сделать это? Обратите внимание, что я не полагаю, что это полное решение для безопасности, очевидно, с помощью средств приведения к базовому классу они все еще могут вызывать это свойство. Это просто означает, что пользователю предлагается ошибка времени компиляции, которая помогает ему понять, что он не может использовать это свойство, и вместо этого ему следует использовать новую функцию в производном классе.

EDIT

Благодаря ответам в этой теме я нашел следующее решение:

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

Ответы [ 3 ]

3 голосов
/ 16 июня 2011

Вы не можете. Самое близкое, что вы могли бы прийти:

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

Лично у меня возникнет соблазн спросить, действительно ли вы должны исходить из этого, если не хотите, чтобы все участники хотя ... могли бы вместо этого использовать композицию?

2 голосов
/ 16 июня 2011

Даже если бы это было возможно, вы на самом деле не хотите «скрывать» средства доступа (как вы заметили, к ним можно просто получить доступ через базовый класс). Вы после предупреждения / ошибки, которая говорит: «Этот метод устарел, и его следует избегать». Таким образом, вы можете захотеть взглянуть на Устаревший атрибут , задокументированный как «Атрибут Устаревший используется для маркировки типов и членов типов, которые больше не должны использоваться» - именно ваш вариант использования.

Редактировать: я настоятельно рекомендую не создавать исключение в методе доступа. Это нарушило бы то, что обычно называют «принципом подстановки Лискова» - то, что вы можете использовать производный класс везде, где требуется базовый класс. Действительно, это просто причудливый язык вокруг того факта, что существующий код, в который вы можете передать производный экземпляр, ожидает .Items геттера, который функционирует разумным образом, а не взрывается при контакте. Если вы выбрасываете исключение, вам может быть сложно отлаживать ошибки в очень труднодоступных местах (учитывая, что ваш суперкласс - черный ящик).

1 голос
/ 16 июня 2011

Вы можете сделать свойство общедоступным в дочернем классе и вызвать исключение, если к нему обращаются. Затем вы должны убедиться, что у вас есть доступ только к свойству базового класса внутри дочернего класса.

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