Наследники, пораждаемые родитлем без открытого конструктора - как?
Есть абстрактный класс. У него - метод Create<T>(params) where T : MyAbstractClass со сложной логикой. Хочу чтобы объекты дочерних классов можно было создать только этим методом (сиречь, они не имели открытых конструкторов). И не нужно было описывать какие-либо дополнительные конструкции. Возможно ли это?
Вот что по этому поводу говорит msdn:
Исходя из того, что каждый наследник должен содержать в себе подобъект родительского класса, скорее всего наследование с private конструктором работать не будет. А можно полюбопытствовать: почему нельзя все, что планируется поместить в метод Create, поместить в конструктор? IMHO: во многих случаях "сложная логика" свидетельствует об ошибках в архитектуре.
Исходя из того, что каждый наследник должен содержать в себе подобъект родительского класса, скорее всего наследование с private конструктором работать не будет.
Как минимум, объявлять их можно:
{
}
public class Child : Parent
{
private Child()
{
}
}
^___________________________^
Потому что метод Create имеет две перегрузки и до 7 параметров. Потому что майкрософт запретили неявное наследование конструкторов (в чем-то они правы) и приведение типов от базового к дочернему (что мешает забить несуществующие поля дефолтными значениями?) и перегрузку методов приведения.
А конструкции вида:
:base(title, insideText, windowClass, titleCompare, insideCompare, classCompare)
{
}
В трех экземплярах (на деле в шести, ибо помимо Create есть еще один способ создания, но не суть) я у себя в коде видеть не желаю.
Сейчас у меня есть пустой публичный конструктор, а все значения из родительского класса в дочерний копируются методом Initialize вызванным после создания. И это ужасно. Для защиты от дурака, я, конечно, могу завести внутреннюю статичную переменную, устанавливать ее внутри Create, а если переменная не установлена, и вызван конструктор - выкидывать исключение... но это ведь ужасно.
{
}
public class Child : Parent
{
private Child()
{
}
}
А разве конструктор без параметров не создается автоматически, если он явно не объявлен?
и приведение типов от базового к дочернему (что мешает забить несуществующие поля дефолтными значениями?)
На то он и родительский класс. И это правильно. Нелогично например Object приводить к Environment.
Потому что метод Create имеет две перегрузки и до 7 параметров.
...
А конструкции вида:
Код :
public MyClass(string title, string insideText = null, string windowClass = null, TextCompareType? titleCompare = null, TextCompareType? insideCompare = null, TextCompareType? classCompare = null) :base(title, insideText, windowClass, titleCompare, insideCompare, classCompare) { }
В трех экземплярах (на деле в шести, ибо помимо Create есть еще один способ создания, но не суть) я у себя в коде видеть не желаю.
а) Если не хотите инициализацию класса сделать в конструкторе базового класса, не делайте её в конструкторе дочернего.
б) Что мешает в дочерних классах перегрузить Create?
в) Что мешает в конструкторе базового класса указать дефалтные значения?
г) Моожет отказаться от наследования и перейти к шаблону?
А вот это уже наводит на мысль о том, что выбран не очень подходящий инструмент для разработки. Уже не первый топик, где вы на C# пытаетесь делать то, что на C++ выглядело бы более логично и естественно. Но это опять-таки, всего лишь по моему скромному мнению...
А вы - не первый, кто мне этого говорит. :)
Ответ всё тот же: я могу писать на С++. Не более. Это прекрасный язык с омерзительным синтаксисом. Код на нем противно не только писать, но и читать.
Так что, пока я не столкнусь с тем, что невозможно реализовать на C# (и, конечно, не такую мелочь, как сейчас) я на нем писать не буду. :) Программируя на C#, я отдыхаю душой. Тут все мило, красиво и пушисто.
Создается. Публичный. Пустой. А если объявить приватный без параметров - не создается.
Это правильно. Вместе с тем верно и то, что приведение экземпляра родительского класса "Кошка" к дочернему классу "Рысь" выглядит также вполне логичным. Так что с этой политикой я не согласен. Впрочем, к теме это не относится. Нельзя, значит нельзя. Приходится выкручиваться.
Хм... к чему бы вы это? Не хочу. Не делаю. :) Как быть?
Да, тоже самое, что и с конструктором. Только тут ситуация еще хуже. На выходе имеем 3(6) методов создания в каждом из дочерних классов - уже "шикарно". И, дальше идет кусок кода в 5-6 строк, для инициализации объекта, передачи его родительскому классу для наполнения родительскими методами, после чего возврат значения. Ужасно! :D Уж лучше фабрика. И то меньше кода будет.
И чем мне это поможет? Мне то нужно создание с параметрами, а не без оных.
А можно поподробнее?
Соответственно, мы должны уметь создавать наследников методами Create и Wait. (что сделано и сейчас) Наследники не должны иметь публичных конструкторов. (а они как раз есть)
Кроме того, это простейшая ситуация, когда все свойства родительского класса привязаны к единственному свойству, которое можно легко передать. А если таких свойст десятки? В общем, интересует универсальное решение.
А можно поподробнее?
А нинада - плохая идея была :)