var value
на самом деле является значением enum (типа ReportStatus), поэтому вы видите стандартное поведение enumValue.ToString () - это имя.
РЕДАКТИРОВАТЬ:
Когда вы сделаете Console.WriteLine(value.GetType())
, вы увидите, что это действительно «ReportStatus», хотя оно упаковано в простой Object
.
Я обычно предпочитаю первый подход, потому что он требует меньше код в дочерних классах.
Однако я признаю, что семантика второго подхода более ясна в тонком смысле. При переопределении свойства говорится, что «реализация этого свойства является частью моей идентичности». Передача аргумента конструктора имеет другое значение: «Я устанавливаю значение в этой другой вещи, которая просто является моим базовым классом». Это подразумевает композицию (has-a), а не наследование (is-a). свойство Value используется только в абстрактный класс?
В этом случае вам обязательно следует использовать первый подход (ориентированный на конструктор), чтобы вы могли скрыть эту деталь реализации от подклассов.
Аналогичным образом, если вам нужно использовать значение в конструкторе; как упомянул Марк , это настоящая техническая причина для использования первого подхода. Хотя в данном конкретном сценарии это не имеет значения, если кто-то позже изменит переопределение свойства для использования какой-либо другой переменной-члена в производном классе, у вас может быть небольшая ошибка.
Это зависит; нужно ли базовому классу знать об этом в ctor? В таком случае подход override
может быть плохой идеей ( virtual
не очень хорошо работает внутри ctor). В противном случае подойдет любой вариант.
Я думаю, что вторая идиома лучше, поскольку она более управляема (если вашему базовому классу требуется несколько свойств, определенных в производном классе, конструктор может запутаться). Также понятнее, откуда приходит информация. Если вы видите свойство Value
, значит, оно определено в подклассе. В первом примере вы должны отслеживать точку определения переменной m_Value
, которую можно изменить в базовом классе.
Я думаю, что это почти то же самое, выберите один путь и придерживайтесь его для согласованности.
Оба ваших решения заставляют производный класс предоставлять значение, и это хорошо; возможная альтернатива, если значение не требуется:
abstract class A {
public string Value {
get;
protected set;
}
}
Мои личные предпочтения - это ваш первый вариант (параметр конструктора), потому что я лично считаю, что он более понятный, но на самом деле это вопрос вкуса.
Это зависит.
Я буду использовать первый способ, если мне нужно изменить Значение
в абстрактном классе.
Я буду использовать второй способ, только если я нужно унаследовать много классов от A
, и где-то мне нужно поместить унаследованные классы в базовый абстрактный класс.
Если оба из вышеперечисленных не верны, я буду использовать второй подход, который больше управляемый и чистый.
Если Значение
используется только в абстрактном классе, я объявлю его как частное
поле вместо свойства.
Я предпочитаю второй. Это позволяет вам предоставить значение без добавления фактического поля в класс, если значение является постоянным или может быть вычислено во время выполнения. Чем меньше у вас состояния (меньше полей), тем легче будет поддерживать код.
Одним из основных преимуществ второго случая является то, что он позволяет подклассу определять поведение для свойства Value, которое может быть более сложным, чем простое скалярное значение. Например, вы можете захотеть вычислить значение на основе других полей, определяемых подклассом. При первом подходе это невозможно, но второй подход позволяет это.