Здравствуйте, SilverCloud, Вы писали:
SC>В чём глубокий смысл сабжа в C#?
Вроде конструктор по умолчанию (без параметров) наследуется, если он не определён явно в наследнике. MSDN:
If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class.
А прочие... видимо, такое поведение было добавлено для лучшего контроля интерфейса класса (всегдя надо явно указывать все конструкторы класса кроме того, что по умолчанию) + видимо, решили, что так программисты будут допускать меньше ошибок "по недосмотру" (не будет возникать ситуаций, когда при добавлении нового конструктора в базовом классе он чудесным образом появится во всех наследниках, как в C++).
В общем-то, конструктор — не просто метод, конструктор инициализирует состояние объекта — логично, что базовый класс не может корректно проинициализировать своих наследников, поэтому каждый класс должен явно декларировать все свои конструкторы, даже если они просто вызывают base().
[... skipped ...]
O>Вроде конструктор по умолчанию (без параметров) наследуется, если он не определён явно в наследнике. MSDN:
O>
O>If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class.
Конечно, это не наследование а генерация конструктора по умолчанию с вызовом конструктора предка, но поведение то же.
Здравствуйте, SilverCloud, Вы писали:
SC>В чём глубокий смысл сабжа в C#?
Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, SilverCloud, Вы писали:
SC>>В чём глубокий смысл сабжа в C#?
VD>Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.
Я вообще-то из братии Java... Тем не менее, слабо верится, что в C# нету super();...
Все говорят, что я садист, но на самом деле я добрый. У меня сердце ребенка. Вот оно — в банке с формалином.
Здравствуйте, AlSy, Вы писали:
VD>>Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.
AS>Я вообще-то из братии Java... Тем не менее, слабо верится, что в C# нету super();...
он у них называется base.
вообше-то, насколько я понял, речь идет не о возможности вызвать конструктор базового класса из конструктора наследника, а возможности создавать экземпляры класса-наследника извне, пользуясь конструктором, который не определен явно в данном классе, но который сгенерен компилятором ("унаследован") по конструктору базового класса с той же самой сигнатурой.
Здравствуйте, dshe, Вы писали:
D>Здравствуйте, AlSy, Вы писали:
VD>>>Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.
AS>>Я вообще-то из братии Java... Тем не менее, слабо верится, что в C# нету super();...
D>он у них называется base.
D>вообше-то, насколько я понял, речь идет не о возможности вызвать конструктор базового класса из конструктора наследника, а возможности создавать экземпляры класса-наследника извне, пользуясь конструктором, который не определен явно в данном классе, но который сгенерен компилятором ("унаследован") по конструктору базового класса с той же самой сигнатурой.
Ну это как-то не хорошо... Что ж мне, если я не хочу, чтобы конструктор наследовался таким образом, обязательно перегружать его в наследнике? ИМХО, неправильно, да и по идее породит море логических ошибок. Если нужна такая фича, проще перегрузить конструтор, а в нем написать super(). И все, и никаких проблем
Все говорят, что я садист, но на самом деле я добрый. У меня сердце ребенка. Вот оно — в банке с формалином.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, SilverCloud, Вы писали:
SC>>В чём глубокий смысл сабжа в C#?
AVK>Одна из причин — необходимость убирать базовые конструкторы.
А когда возникает такая необходимость? Мне в голову ни один пример не приходит.
Но даже если такая необходимость вдруг возникнет (в чем я лично сомневаюсь), никто не мешает перекрыть конструктор и сделать его protected или private.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, AndrewVK, Вы писали:
AVK>>Здравствуйте, SilverCloud, Вы писали:
SC>>>В чём глубокий смысл сабжа в C#?
AVK>>Одна из причин — необходимость убирать базовые конструкторы.
Д>А когда возникает такая необходимость? Мне в голову ни один пример не приходит. Д>Но даже если такая необходимость вдруг возникнет (в чем я лично сомневаюсь), никто не мешает перекрыть конструктор и сделать его protected или private.
Необходимость возникает когда в наследнике добавляется поле, которое должно быть инициализировано (в конструкторе) ненулевым значением. Так называемое "наследование конструкторов" скорее всего приведет к тому, что у класса-наследника будет много конструкторов, унаследованных от предков самой разной близости, которые не инициализируют объект полностью. А это чревато ошибками. На мой взгляд, гораздо проще (и безопаснее) явно объявить конструктор, в котором просто вызвать base, чем скрывать за private или protected лишние конструкторы.
Здравствуйте, Дарней, Вы писали:
Д>А когда возникает такая необходимость? Мне в голову ни один пример не приходит.
Очень странно. Такое довольно часто встречается.
class Base
{
public Base(bool someFlag)
{}
}
class Derived
{
public Derived() : base(true)
{}
}
Д>Но даже если такая необходимость вдруг возникнет (в чем я лично сомневаюсь), никто не мешает перекрыть конструктор и сделать его protected или private.
Что такое перекрыть конструктор? Такого понятия в C# нет.
Здравствуйте, AndrewVK, Вы писали:
AVK>Очень странно. Такое довольно часто встречается. AVK>
AVK>class Base
AVK>{
AVK> public Base(bool someFlag)
AVK> {}
AVK>}
AVK>class Derived
AVK>{
AVK> public Derived() : base(true)
AVK> {}
AVK>}
AVK>
Ну а смысл то в чем? Если Base(bool someFlag) используется для каких-то внутренних целей данной иерархии, то разумнее сделать его protected.
Почему Base(bool someFlag) должен обязательно быть виден для всех, а Derived(bool someFlag) ни в коем случае нет?
AVK>Что такое перекрыть конструктор? Такого понятия в C# нет.
Я думал, несложно догадаться.
class Base
{
public Base(bool someFlag)
{}
}
class Derived : Base
{
protected Derived(bool someFlag) : base(someFlag)
{}
public Derived() : base(true)
{}
}
Здравствуйте, Дарней, Вы писали:
AVK>>Очень странно. Такое довольно часто встречается. AVK>>
AVK>>class Base
AVK>>{
AVK>> public Base(bool someFlag)
AVK>> {}
AVK>>}
AVK>>class Derived
AVK>>{
AVK>> public Derived() : base(true)
AVK>> {}
AVK>>}
AVK>>
Д>Ну а смысл то в чем? Если Base(bool someFlag) используется для каких-то внутренних целей данной иерархии, то разумнее сделать его protected.
Смысл в том, что алгоритмы Derived рассчитаны на то, что алгоритмы Base будут работать всегда с флажком true. protected конструктор делать нельзя, поскольку класс Base может быть самоценен.
AVK>>Что такое перекрыть конструктор? Такого понятия в C# нет.
Д>Я думал, несложно догадаться.
И о чем я должен догадаться? Что там физически должно происходить?
Здравствуйте, AndrewVK, Вы писали:
AVK>Смысл в том, что алгоритмы Derived рассчитаны на то, что алгоритмы Base будут работать всегда с флажком true. protected конструктор делать нельзя, поскольку класс Base может быть самоценен.
И вот ради такого редкого случая заставлять всех писать кучу ненужного кода?
Который, к тому же, прекрасно решается другими средствами.
AVK>И о чем я должен догадаться? Что там физически должно происходить?
о смысле слова "перекрыть". Иными словами, создать конструктор с такими же параметрами, но с другим спецификатором доступа.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, AndrewVK, Вы писали:
Д>И вот ради такого редкого случая заставлять всех писать кучу ненужного кода?
Для того, чтобы оценить какие случаи редкие, а какие нет, можно посчитать сколько раз конструктор определяется только для того, чтобы вызвать базовый (с теми же параметрами). Я думаю, что наоборот, необходимость в "наследовании конструкторов" возникает весьма нечасто.
Дарней,
AVK>> Смысл в том, что алгоритмы Derived рассчитаны на то, что алгоритмы AVK>> Base будут работать всегда с флажком true. protected конструктор AVK>> делать нельзя, поскольку класс Base может быть самоценен.
Д> И вот ради такого редкого случая заставлять всех писать кучу ненужного Д> кода? Который, к тому же, прекрасно решается другими средствами.
Какими средствами? Т.е., если инвариантом Derived является то, что Base
проинициализирован someFlag = true, то как это обеспечить при открытом
конструкторе Base(bool)?
Варианты явным образом закрывать конструкторы подходят не вполне, т.к.
при добавлении базовых классов необходимо будет просматривать всех
наследников, что в общем случае сделать нереально.
Имхо, то же самое относится и к обычным функциям, но почему-то в C# этот
вопрос решили по-другому...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, AlSy, Вы писали:
AS>Ну это как-то не хорошо... Что ж мне, если я не хочу, чтобы конструктор наследовался таким образом, обязательно перегружать его в наследнике? ИМХО, неправильно, да и по идее породит море логических ошибок.
Каких? Аргументы, плиз, в студию.
AS> Если нужна такая фича, проще перегрузить конструтор, а в нем написать super(). И все, и никаких проблем
Помтоу что это море никому не нужного кода. Вот представь... Создал я реализацию некой коллекции. Причем в рассчете на то, что напрямую ее создавать никто не будет, а на против, будут порождать он нее наследников. Так вот в этой коллекции есть, предположим, 20 конструкторов. Их все прейдется описать в наследнике. Да еще не ошибиться.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
SC>>В чём глубокий смысл сабжа в C#?
AVK>Одна из причин — необходимость убирать базовые конструкторы.
Лучше бы решили проблему скрытия методов в наследнике. А то нобходимость скрывать конструкторы возникает не чаще чем обычные методы. В общем, не логично.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, dshe, Вы писали:
D>Необходимость возникает когда в наследнике добавляется поле, которое должно быть инициализировано (в конструкторе) ненулевым значением. Так называемое "наследование конструкторов" скорее всего приведет к тому, что у класса-наследника будет много конструкторов, унаследованных от предков самой разной близости, которые не инициализируют объект полностью. А это чревато ошибками. На мой взгляд, гораздо проще (и безопаснее) явно объявить конструктор, в котором просто вызвать base, чем скрывать за private или protected лишние конструкторы.
Ну, и почему не поступать так же как с конструкторами без параметров? Ну, наследовать конструкторы если в наследнике они не определены явно.
А еще лучше позволить вручную скрывать любые методы.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.