protected readonly в наследнике
От: Sharov Россия  
Дата: 19.02.21 13:00
Оценка:
Здравствуйте.

Дан сл. код:
  public abstract class Foo
    {
        protected readonly int Field;

        protected Foo()
        {
            Field = 5;
        }
    }

    public abstract class Bar:Foo
    {
       protected Bar():base()
        {
            Field = 5; //ошибка!!!
        }
    }


Код выше не компилируется по причине того, что Field readonly. Я понимаю, что конструктор это такой спец.
метод для создания объектов, соотв. readonly поля возможно менять(по сути давать значения) только
в этих спец. методах. Но почему бы не разрешить это также делать и наследникам, т.е. ограниченному числу
других спец. методов? Чем это плохо, что я упускаю из виду?
Кодом людям нужно помогать!
Re: protected readonly в наследнике
От: Silver_S Ниоткуда  
Дата: 19.02.21 17:27
Оценка: 4 (1)
Здравствуйте, Sharov, Вы писали:
S> Но почему бы не разрешить это также делать и наследникам, т.е. ограниченному числу других спец. методов?

В любом случае, есть ситуации когда не хочется давать наследникам такую возможность. Поэтому пришлось бы еще одно ключевое слово для такой возможности.
Но надо ли оно? Особенно если это не int, а большой объект. Базовый класс создает объект, а производный его выкидывает и перезаписывает — неэффективно.
Если создание объекта надо вынести наружу — этот объект можно передавать как параметр в конструктор базового класса.
Re: protected readonly в наследнике
От: HFTMan  
Дата: 19.02.21 17:28
Оценка: 4 (1) +2
Здравствуйте, Sharov, Вы писали:

S>Код выше не компилируется по причине того, что Field readonly. Я понимаю, что конструктор это такой спец.

S>метод для создания объектов, соотв. readonly поля возможно менять(по сути давать значения) только
S>в этих спец. методах. Но почему бы не разрешить это также делать и наследникам, т.е. ограниченному числу
S>других спец. методов? Чем это плохо, что я упускаю из виду?
 public abstract class Foo
    {
        protected int Field
        {
            get;
            init;
        }

        protected Foo()
        {
            Field = 5;
        }
    }

    public abstract class Bar : Foo
    {
        protected Bar() : base()
        {
            Field = 5; //нет ошибки
        }
    }
Отредактировано 19.02.2021 17:29 HFTMan . Предыдущая версия .
Re[2]: protected readonly в наследнике
От: Sharov Россия  
Дата: 19.02.21 17:32
Оценка:
Здравствуйте, Silver_S, Вы писали:

S_S>В любом случае, есть ситуации когда не хочется давать наследникам такую возможность. Поэтому пришлось бы еще одно ключевое слово для такой возможности.


private?

S_S>Но надо ли оно? Особенно если это не int, а большой объект. Базовый класс создает объект, а производный его выкидывает и перезаписывает — неэффективно.


Эффективно\неэфективно судить должен разработчик соотв. классов (наследников), а создатели компилятора могли бы и предоставить
такую возможность.
Кодом людям нужно помогать!
Re: protected readonly в наследнике
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.02.21 01:05
Оценка: 4 (1) +1
Здравствуйте, Sharov, Вы писали:

S>в этих спец. методах. Но почему бы не разрешить это также делать и наследникам, т.е. ограниченному числу

S>других спец. методов? Чем это плохо, что я упускаю из виду?

Переменная может быть задействована в некотором коде вызываемом из конструктора базового класса. Если инициализировать ее в наследнике, есть вероятность нарваться на дефольтное значение.

В таких случаях лучше задавать значение через параметр конструктора базового типа.

    public abstract class Foo
    {
        protected readonly int Field;

        protected Foo(int field)
        {
            Field = field;
        }
    }

    public abstract class Bar : Foo
    {
        protected Bar() : base(5)
        {
        }
    }
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: protected readonly в наследнике
От: varenikAA  
Дата: 20.02.21 01:37
Оценка: 4 (1) -2 :)
Здравствуйте, Sharov, Вы писали:

    public abstract class Foo
    {
        protected readonly int Field;

        protected Foo()
        {
            Field = 5;
        }

    }

    public abstract class Bar : Foo
    {
        protected new readonly int Field;
        protected Bar() : base()
        {
            Field = 15; 
        }
    }
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: protected readonly в наследнике
От: Sharov Россия  
Дата: 20.02.21 08:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Переменная может быть задействована в некотором коде вызываемом из конструктора базового класса. Если инициализировать ее в наследнике, есть вероятность нарваться на дефольтное значение.


Справедливо, с др. стороны, если возможно поломка инкапсуляции, зачем тогда делать переменную protected?
Кодом людям нужно помогать!
Re[3]: protected readonly в наследнике
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.02.21 21:38
Оценка: +1
Здравствуйте, Sharov, Вы писали:

S>Справедливо, с др. стороны, если возможно поломка инкапсуляции, зачем тогда делать переменную protected?


Так она неизменяемая. Есть много случаев, когда наследники должны иметь доступ к данным или сервисам предков. Например, это может быть логер.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.