Принято ли использовать приватный метод вместо того, чтобы избегать виртуальных членов в конструкторе? - PullRequest
4 голосов
/ 23 июня 2010

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

public class EntityAlpha {
    public virtual string Value { get; protected set; }

    public EntityAlpha(string value) {
        Value = value;
    }
}

для замены на

public class EntityAlpha {
    public virtual string Value { get; protected set; }

    public EntityAlpha(string value) {
         AssignValue(value);
    }

    private void AssignValue(string value) {
        Value = value;
    }
}

Каковы последствия использования этого дополнительного метода?Это все еще опасно, как использование виртуального члена в конструкторе или худший ?!Как проверить, не вредно ли это предположение?

Ответы [ 5 ]

10 голосов
/ 23 июня 2010

У вас фактически такая же проблема, только теперь код труднее читать.

Ключ разрабатывает ваш класс так, чтобы конструктор не не достигал каких-либо виртуальных членов, даже косвенно через другие методы.

4 голосов
/ 23 июня 2010

Это все так же опасно;все, что вы делаете, это скрываете опасность и запутываете код.

Если Value поддерживается фактическим полем данных, скажем, m_Value, вы можете предотвратить проблему, назначив m_Value напрямую.

4 голосов
/ 23 июня 2010

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

1 голос
/ 23 июня 2010

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

1 голос
/ 23 июня 2010

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

...