Создать объект производного класса из объекта базового класса - PullRequest
1 голос
/ 04 мая 2011

в моем приложении у меня есть древовидная структура данных.Узлы относятся к классу X. У меня есть другой класс Y, который получен из X. В конце концов, мне нужно «преобразовать / изменить» узлы из типа X в тип Y - во всей древовидной структуре.

Есть ли простой способ сделать это, или мне нужно проанализировать все дерево, воссоздав его, создав экземпляр каждого узла с типом Y?

Заранее спасибо,
Фрэнк

Эдит говорит: Спасибо за все ваши ответы!Я пытаюсь объяснить, почему мне нужно такое поведение: давайте представим, мы обслуживаем.Мы хотим смоделировать наше портфолио в виде дерева.Один узел может быть «супом», и мы предлагаем картофельные супы, томатные супы и супы с лапшой - каждый из них является дочерним узлом узла «супы».После завершения моделирования мы представляем дерево покупателю, который выбирает «базовый кейтеринг-сервис».Это означает, что она может выбрать один из супов для своего обеда.
Для моей базовой модели это означает, что мне нужно дополнительное поле «IsSelected», которое мне не нужно, когда провизор создает портфель.Поэтому я хочу получить класс Y из класса X с дополнительным полем.

Ответы [ 5 ]

2 голосов
/ 04 мая 2011

Да, вам придется пройти по всему дереву и заново создать все узлы.

Что делает хорошей идеей пересмотреть дизайн, который привел к этой ситуации.

1 голос
/ 04 мая 2011

Фактический тип объекта определяется при его создании и не может быть изменен впоследствии. Так что нет, другого пути нет.

0 голосов
/ 04 мая 2011

Поскольку никто еще не указал на это ...

Если вы создаете объект как Y, его можно привести к X, а затем снова к Y, но объектсозданный как X не может быть приведен к Y.Это просто базовое поведение ОО.

Это означает, что если вы создаете свой источник данных в виде иерархического списка Y, вы можете затем преобразовать их в X, а затем обратно в Y, когда это подходит.

Фактически, если вы используете Linq, в классе Enumerable существует метод расширения, называемый Cast () .Вы можете использовать его следующим образом:

public class Animal {   }

public class Dog : Animal {   }

List<Dog> dogs = new List<Dog>();
List<Animal> animals = dogs.Cast<Animal>().ToList();

Вы не упомянули, что вы используете (WinForms / WPF / Silverlight / ASP.NET), но в WPF есть HierarchicalDataTemplate, который можно привязать к списку, которыйявляется подобным узлу (то есть каждый элемент в списке может иметь детей).Использование чего-то подобного с Cast() сверху должно хорошо работать.

Конечно, это не значит, что вы не должны просматривать свой код и смотреть, действительно ли это лучший способ сделать это (какдругие тоже говорили).

0 голосов
/ 04 мая 2011

Возможно неявное или явное приведение оператора может помочь вам, но я думаю, что некоторые плохие конструкции приводят к этому:

public static implicit operator MyTypeB( MyTypeA a ) {
  MyTypeB b = new MyTypeB();
  // copy all a properties
  return b;
}

Люди говорят, что вам понадобитсяцикл и воссоздание всех узлов, но таким образом все узлы могут быть использованы как узлы разных типов, потому что они выполняют работу по воссозданию при необходимости.

Но обратите внимание, что перегрузка оператора приведения не должна использоваться, если некоторые данныеlost.

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

0 голосов
/ 04 мая 2011

Изменение типа объекта обычно вызывает большой запах кода.Если это необходимо из-за того, что часть поведения объекта должна измениться, взгляните на Шаблон разработки стратегии .

Но в любом случае вам, как правило, придется обходить все дерево, чтобы изменить стратегию на каждом узле.Если действительно все объекты должны изменить поведение, вы также можете подумать о комбинации с Flyweight Design Pattern .Но, как уже упоминалось, здесь слишком мало информации, чтобы дать хороший совет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...