Как скрыть унаследованное свойство в классе, не изменяя наследованный класс (базовый класс)?

Ctrl + L будет обычно очищать экран. Работы от подсказки Bash (очевидно), и в GDB и много других подсказок.

43
задан user151019 9 May 2012 в 11:19
поделиться

3 ответа

Я чувствую запах кода. Я считаю, что вы должны наследовать базовый класс, только если вы реализуете все функции этого базового класса. То, что вы делаете, на самом деле не отражает должным образом объектно-ориентированные принципы. Таким образом, если вы хотите наследовать от своей базы, вы должны реализовать Name, иначе у вас будет неправильное наследование. Ваш класс A должен быть вашим базовым классом, а ваш текущий базовый класс должен наследовать от A, если вы этого хотите, а не наоборот.

Однако, не уходите слишком далеко от прямого вопроса. Если вы действительно хотите нарушить «правила» и продолжить путь, который вы выбрали, - вот как вы можете это сделать:

По соглашению реализуется свойство, но при вызове этого свойства создается исключение NotImplementedException - хотя мне это тоже не нравится. Но это мое личное мнение, и это не меняет того факта, что это соглашение все еще остается в силе.

Если вы пытаетесь сделать свойство устаревшим (и оно объявлено в базовом классе как виртуальное), то вы можете использовать Устаревшее атрибут на нем:

[Obsolete("This property has been deprecated and should no longer be used.", true)]
public override string Name 
{ 
    get 
    { 
        return base.Name; 
    }
    set
    {
        base.Name = value;
    }
}

( Edit: Как Брайан указал в комментариях, второй параметр атрибута вызовет ошибку компилятора, если кто-то ссылается на свойство Name, поэтому они не смогут используйте его, даже если вы реализовали его в производном классе.)

Или, как я уже упоминал, используйте NotImplementedException:

public override string Name
{
    get
    {
        throw new NotImplementedException();
    }
    set
    {
        throw new NotImplementedException();
    }
}

Однако, если свойство не объявлено как виртуальное, затем вы можете использовать ключевое слово new для его замены:

public new string Name
{
    get
    {
        throw new NotImplementedException();
    }
    set
    {
        throw new NotImplementedException();
    }
}

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

[Obsolete("Don't use this", true)]
public override string Name { get; set; }

или:

[Obsolete("Don't use this", true)]
public new string Name { get; set; }

В зависимости от того, был ли он объявлен как виртуальный в базовом классе.

62
ответ дан 26 November 2019 в 22:30
поделиться

While technically the property won't be hidden, one way to strongly discourage its use is to put attributes on it like these:

[Browsable(false)]
[Bindable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[EditorBrowsable(EditorBrowsableState.Never)]

This is what System.Windows.Forms does for controls that have properties that don't fit. The Text property, for instance, is on Control, but it doesn't make sense on every class that inherits from Control. So in MonthCalendar, for instance, the Text property appears like this (per the online reference source):

[Browsable(false),
    EditorBrowsable(EditorBrowsableState.Never),
    Bindable(false), 
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text {
    get { return base.Text; }
    set { base.Text = value; }
}
  • Browsable - whether the member shows up in the Properties window
  • EditorBrowsable - whether the member shows up in the Intellisense dropdown

EditorBrowsable(false) won't prevent you from typing the property, and if you use the property, your project will still compile. But since the property doesn't appear in Intellisense, it won't be as obvious that you can use it.

33
ответ дан 26 November 2019 в 22:30
поделиться

Вы не можете, в этом весь смысл наследования: подкласс должен предлагать все методы и свойства базы class.

Вы можете изменить реализацию, чтобы генерировать исключение при вызове свойства (если оно было виртуальным) ...

1
ответ дан 26 November 2019 в 22:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: