Кастинг с базы на производную? - PullRequest
3 голосов
/ 14 декабря 2011

Можно ли привести объект из базы к производному? Например, допустим, у меня есть один базовый объект: Animal. Из этого я получил несколько других классов: Cat, Dog. Теперь мне нужно Animal, но тип на данный момент не имеет значения. Итак,

Animal blankCanvas = new Animal();

По пути я передумал и теперь хочу изменить это Animal на Dog. Однако я не понимаю, как бы я поступил так. Я знаю бизнес-правила для перехода из Animal в Dog, но я просто не знаю, как это реализовать.

Ответы [ 5 ]

3 голосов
/ 14 декабря 2011

Да, вы можете привести базовую ссылку к производной ссылке.

Но вы, похоже, хотите преобразовать экземпляр. Это не кастинг, и это напрямую невозможно.

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

Может иметь смысл следующее:

Animal blankCanvas = null;
...
blankCanvas = new Dog();

Чтобы помочь вам сохранить правильный путь, определите Animal как abstract class
В конце концов, что представляет собой экземпляр Animal?

2 голосов
/ 14 декабря 2011

Вы можете использовать статический метод в производном классе следующим образом:

/// <summary>
/// Dog.
/// </summary>
class Dog : Animal
{
    /// <summary>
    /// Initializes a new instance of the <see cref="Dog"/> class.
    /// </summary>
    /// <param name="type">The type.</param>
    public Dog(string type)
        : base(type)
    { }

    /// <summary>
    /// Gets a dog from an animal.
    /// </summary>
    /// <param name="animal">The animal.</param>
    /// <returns></returns>
    public static Dog FromAnimal(Animal animal)
    {
        return new Dog(animal.Type);
    }
}

/// <summary>
/// Animal.
/// </summary>
class Animal
{
    /// <summary>
    /// Gets or sets the type.
    /// </summary>
    /// <value>The type.</value>
    public string Type { get; private set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="Animal"/> class.
    /// </summary>
    /// <param name="type">The type.</param>
    public Animal(string type)
    {
        this.Type = type;
    }
}

Или использовать один фабричный класс для управления всеми необходимыми преобразованиями.

1 голос
/ 14 декабря 2011

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

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

0 голосов
/ 14 декабря 2011

Экземпляр вашего класса, когда-то "рожденный как животное", будет жить как Animal.Вы можете попытаться привести его к производному классу, но, поскольку сам экземпляр остается Animal, он потерпит неудачу во всех случаях.

Вот несколько советов, как вы можете изменить его на другой класс:

Вы можете реализовать пользовательское преобразование в другой класс, явно реализовав его с помощью статических методов, например, вы можете реализовать что-то вроде:

public class Cat : Animal
{
 public Cat FromAnimal(Animal animal)
 {
   return new Cat(animal) {Eyes = Color.Blue, ... };
 }
}

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

Вы можете реализовать глубокое клонирование своего экземпляра с явными типами возврата производных типов.

Тогда вы просто замените свой старый Animal новым бордом Catи используй его везде ...

0 голосов
/ 14 декабря 2011

Насколько я знаю, вы не можете сделать это с помощью приведения, но у вас может быть конструктор в Dog, который будет принимать, и animal в качестве параметра, подобного этому:

Public Dog(Animal pAnimal)
{
    //do stuff...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...