Переопределение C# переменной в производном классе с другим типом данных - PullRequest
2 голосов
/ 20 июня 2020

Мой базовый класс объявляет:

public double Value;

Мой производный класс объявляет:

public new decimal Value;

В подсказке по использованию ключевого слова new говорится: «...Use the new keyword if hiding was intended.» .

Это объяснение не кажется правильным. При использовании ключевого слова new базовая переменная не скрывается. Он сохраняет обе переменные с одинаковыми именами и даже с разными значениями.

Я понимаю, что на моей стороне есть проблема с дизайном, но я хотел бы знать, почему ключевое слово new не действительно скрыть переменную базового класса. Кроме того, почему ключевое слово new даже доступно, если это означало бы проблему дизайна (изменение типа данных в производном классе). Можно ли здесь использовать dynamic? Проблема в следующем: по большей части double в порядке. Однако в некоторых производных классах это должно быть decimal.

Этот вопрос сосредоточен на использовании ключевого слова new для переменных в производных классах, а не на обсуждении различий между double и decimal.

Спасибо.

1 Ответ

4 голосов
/ 20 июня 2020

Вы смешали понятия о (new, override) и (property, field).

Я предоставлю некоторую информацию о них и сделаю свое предложение. Мое предложение относится к третьей части.

Если этот пост не отвечает на ваш вопрос, отредактируйте его, указав вариант использования.


new не override

new - это «скрыть» свойство / поле базового класса, которое НЕ переопределяет virtual функции.

В итоге:

  1. override используется, когда необходимо изменить функцию virtual базового класса или определить функцию abstract.

Если дочерний класс вызывает функцию foo базового класса, которая вызывает виртуальную функцию bar, будет вызываться ДЕТСКАЯ версия bar, а не базовая версия.

Для new,

Если дочерний класс вызывает функцию foo базового класса, которая вызывает функцию bar, будет вызываться БАЗОВАЯ версия bar, а не дочерняя версия.

Я редко использую новую, поэтому не могу посоветовать, как ее использовать.

Ссылка Разница между новой и переопределенной


Поле нельзя переопределить.

public class foo
{
    public double field; // This is field
    public int property  // This is property
    {
        get{ return 1  };
    }
}
  1. Свойство является оболочкой для функций получения / установки.

  2. Свойство можно переопределить ( из-за # 1), но поля не могут быть переопределены.

Ref В чем разница между полем и свойством?


Предложение

Мне пришло в голову реализовать Value как свойство object

public class foo
{
    public virtual object Value
    {
        get; set;
    }
}

Затем обернуть его в нужный тип, но это будет стоить коробка и распаковка .

Однако, если ваш случай не критичен к производительности, все в порядке.

public class bar : foo
{
    public override object Value
    {
        get{ // something different
        }; 
        set{ // something different
        };
    }

    public double DesiredValue
    {
        get{  return (double)Value };
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...