Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Наследники, пораждаемые родитлем без открытого конструктора - как?

9.7K
04 января 2012 года
Vitamant
228 / / 07.02.2011
C# 4.0
Есть абстрактный класс. У него - метод Create<T>(params) where T : MyAbstractClass со сложной логикой. Хочу чтобы объекты дочерних классов можно было создать только этим методом (сиречь, они не имели открытых конструкторов). И не нужно было описывать какие-либо дополнительные конструкции. Возможно ли это?
20K
04 января 2012 года
sem2711
124 / / 23.09.2009
Цитата:
сиречь, они не имели открытых конструкторов


Вот что по этому поводу говорит msdn:

Цитата:
If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class.


Исходя из того, что каждый наследник должен содержать в себе подобъект родительского класса, скорее всего наследование с private конструктором работать не будет. А можно полюбопытствовать: почему нельзя все, что планируется поместить в метод Create, поместить в конструктор? IMHO: во многих случаях "сложная логика" свидетельствует об ошибках в архитектуре.

9.7K
05 января 2012 года
Vitamant
228 / / 07.02.2011
Цитата: sem2711
Вот что по этому поводу говорит msdn:
Исходя из того, что каждый наследник должен содержать в себе подобъект родительского класса, скорее всего наследование с private конструктором работать не будет.


Как минимум, объявлять их можно:

 
Код:
public abstract class Parent
    {
    }

    public class Child : Parent
    {
        private Child()
        {
        }
    }


Цитата: sem2711
А можно полюбопытствовать: почему нельзя все, что планируется поместить в метод Create, поместить в конструктор? IMHO: во многих случаях "сложная логика" свидетельствует об ошибках в архитектуре.


^___________________________^
Потому что метод 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 есть еще один способ создания, но не суть) я у себя в коде видеть не желаю.

Сейчас у меня есть пустой публичный конструктор, а все значения из родительского класса в дочерний копируются методом Initialize вызванным после создания. И это ужасно. Для защиты от дурака, я, конечно, могу завести внутреннюю статичную переменную, устанавливать ее внутри Create, а если переменная не установлена, и вызван конструктор - выкидывать исключение... но это ведь ужасно.
277
05 января 2012 года
arrjj
1.7K / / 26.01.2011
Цитата: Vitamant
Как минимум, объявлять их можно:
 
Код:
public abstract class Parent
    {
    }

    public class Child : Parent
    {
        private Child()
        {
        }
    }



А разве конструктор без параметров не создается автоматически, если он явно не объявлен?

Цитата: Vitamant

и приведение типов от базового к дочернему (что мешает забить несуществующие поля дефолтными значениями?)


На то он и родительский класс. И это правильно. Нелогично например Object приводить к Environment.

Цитата: Vitamant

Потому что метод 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?

в) Что мешает в конструкторе базового класса указать дефалтные значения?

г) Моожет отказаться от наследования и перейти к шаблону?

20K
05 января 2012 года
sem2711
124 / / 23.09.2009
[QUOTE=Vitamant]майкрософт запретили неявное наследование конструкторов (в чем-то они правы) и приведение типов от базового к дочернему [/QUOTE]
А вот это уже наводит на мысль о том, что выбран не очень подходящий инструмент для разработки. Уже не первый топик, где вы на C# пытаетесь делать то, что на C++ выглядело бы более логично и естественно. Но это опять-таки, всего лишь по моему скромному мнению...
9.7K
05 января 2012 года
Vitamant
228 / / 07.02.2011
Цитата: sem2711
А вот это уже наводит на мысль о том, что выбран не очень подходящий инструмент для разработки. Уже не первый топик, где вы на C# пытаетесь делать то, что на C++ выглядело бы более логично и естественно. Но это опять-таки, всего лишь по моему скромному мнению...


А вы - не первый, кто мне этого говорит. :)
Ответ всё тот же: я могу писать на С++. Не более. Это прекрасный язык с омерзительным синтаксисом. Код на нем противно не только писать, но и читать.
Так что, пока я не столкнусь с тем, что невозможно реализовать на C# (и, конечно, не такую мелочь, как сейчас) я на нем писать не буду. :) Программируя на C#, я отдыхаю душой. Тут все мило, красиво и пушисто.

Цитата:
А разве конструктор без параметров не создается автоматически, если он явно не объявлен?


Создается. Публичный. Пустой. А если объявить приватный без параметров - не создается.

Цитата:
На то он и родительский класс. И это правильно. Нелогично например Object приводить к Environment.


Это правильно. Вместе с тем верно и то, что приведение экземпляра родительского класса "Кошка" к дочернему классу "Рысь" выглядит также вполне логичным. Так что с этой политикой я не согласен. Впрочем, к теме это не относится. Нельзя, значит нельзя. Приходится выкручиваться.

Цитата:
а) Если не хотите инициализацию класса сделать в конструкторе базового класса, не делайте её в конструкторе дочернего.


Хм... к чему бы вы это? Не хочу. Не делаю. :) Как быть?

Цитата:
б) Что мешает в дочерних классах перегрузить Create?


Да, тоже самое, что и с конструктором. Только тут ситуация еще хуже. На выходе имеем 3(6) методов создания в каждом из дочерних классов - уже "шикарно". И, дальше идет кусок кода в 5-6 строк, для инициализации объекта, передачи его родительскому классу для наполнения родительскими методами, после чего возврат значения. Ужасно! :D Уж лучше фабрика. И то меньше кода будет.

Цитата:
в) Что мешает в конструкторе базового класса указать дефалтные значения?


И чем мне это поможет? Мне то нужно создание с параметрами, а не без оных.

Цитата:
г) Моожет отказаться от наследования и перейти к шаблону?


А можно поподробнее?

9.7K
05 января 2012 года
Vitamant
228 / / 07.02.2011
Вот, выкладываю код того, что пытаюсь облагородить. Заодно, выслушаю любую критику по теме. (Во вложении, форум не тянет)[ATTACH]5470[/ATTACH]

Соответственно, мы должны уметь создавать наследников методами Create и Wait. (что сделано и сейчас) Наследники не должны иметь публичных конструкторов. (а они как раз есть)
Кроме того, это простейшая ситуация, когда все свойства родительского класса привязаны к единственному свойству, которое можно легко передать. А если таких свойст десятки? В общем, интересует универсальное решение.
277
05 января 2012 года
arrjj
1.7K / / 26.01.2011
Цитата: Vitamant

А можно поподробнее?



А нинада - плохая идея была :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог