Наследование и преобразование объектов - PullRequest
1 голос
/ 16 марта 2009

У меня есть класс SalesMan, который унаследован от класса User, а также реализует интерфейс ISalesMan.

public class SalesMan : User, ISalesMan
{
 ...
}

Мне нужно преобразовать User объекты в SalesMan объекты. Я понимаю, что прямое приведение объектов типа User к типу SalesMan невозможно. Как мне сделать конвертацию? Я думаю о двух разных путях:

  1. Создание конструктора для класса SalesMan, который принимает параметр User и инициализирует новый объект SalesMan на основе заданного User.

  2. Создание нового метода для класса SalesMan, который принимает User в качестве параметра и возвращает новый объект SalesMan на основе заданного параметра User.

... или есть еще более разумный способ решить эту проблему?

Ответы [ 5 ]

4 голосов
/ 16 марта 2009

Конструктор, описанный в Варианте 1, - это то, что я ожидал бы найти, если бы возился с незнакомым API.

Хотя это могут быть скучные звери, и вы можете забыть обновить их при добавлении новых полей в класс User. Поэтому (если позволяют соображения производительности), подумайте о написании «интеллектуального» конструктора с использованием отражения в соответствии с примером .

В отношении конструкторов по сравнению с фабричными методами Руководство по проектированию фреймворка предлагает следующий совет:

  • НЕОБХОДИМО предпочитать конструкторов фабрикам, потому что они как правило, более удобный, последовательный, и удобный то специализированный строительные механизмы.

  • РАССМОТРИТЕ использование фабрики, если вам нужно больше контроля, чем может быть обеспечивается конструкторами над создание экземпляров.

  • НЕ используйте фабрику, где разработчик может не знать, какой тип
    построить, например, при кодировании
    по базовому типу или интерфейсу.

  • РАССМОТРЕТЬ использование фабрики, если использование именованного метода является единственным способом сделать операцию само за себя.

0 голосов
/ 16 марта 2009

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

public static explicit operator SalesMan(User user)
{
    // Your logic to create a new SalesMan using data from user.
}

Чтобы определить, какое решение является умнее , потребуется больше информации, чем было предоставлено в исходном сообщении. Тем не менее, я склонен проветривать стороны полноты и универсальности, и хотел бы рассмотреть и то и другое.

public class SalesMan
{
    public SalesMan(User user)
    {
        // Your logic to create a new SalesMan using data from user.
    }

    public static explicit operator SalesMan(User user)
    {
        return new SalesMan(user);
    }
}

И Ян прав. Общее практическое правило - использовать фабрику только тогда, когда у вас есть функциональное требование, которое не может быть выполнено с помощью конструктора, или когда ограничения на языке начинают мешать вам. Например, нужны два разных конструктора с одинаковой подписью.

0 голосов
/ 16 марта 2009

Я использую вариант 1. Конструктор обновления или конструктор преобразования.

0 голосов
/ 16 марта 2009

Если вы действительно хотите создать объект SalesMan из объекта User, то подойдет любой из описанных вами вариантов.

Но я думаю, вам нужно спросить себя, что вы пытаетесь сделать. Когда / почему Пользователь становится SalesMan? Вы пытаетесь изменить поведение существующего объекта? Изменяется ли поведение в вашей системе регулярно?

В зависимости от ваших потребностей, вы можете рассмотреть возможность использования шаблонов Стратегии или Шаблонного метода.

0 голосов
/ 16 марта 2009

Вариант 1 - самый аккуратный и интуитивно понятный.

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