Reputation: 1271
Is it possible to cast an object from a base to a derived one? For instance, let's say I have one base object: Animal
. From this I have derived a couple of other classes: Cat
, Dog
.
Now I need an Animal
but the type at this moment doesn't really matter. So,
Animal blankCanvas = new Animal();
Along the way I changed my mind and now want to change that Animal
to a Dog
. However, I don't understand how I would go about doing that. I know the business rules to convert from an Animal to a Dog but I just don't know how to implement that.
Upvotes: 3
Views: 2575
Reputation: 2972
You can either use a static method on the derived class like this:
/// <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;
}
}
Or use a single factory class to manage all the conversions you need.
Upvotes: 2
Reputation: 273169
Yes, you can cast a base reference to a derived reference.
But you seem to want to convert an instance. That is not casting and it is not directly possible.
Your logic should be such that you know what type you want at the point when you create it.
The following could make sense:
Animal blankCanvas = null;
...
blankCanvas = new Dog();
To help you to keep the correct path, define Animal as an abstract class
After all, what does an instance of Animal
represent?
Upvotes: 3
Reputation: 12524
The instance of your class once "born as animal" will live its life as an Animal
. You can try to cast it to derived class, but since the instance itself remains Animal
it will fail in all cases.
Here are some suggestions how you can change it to other class:
You can implement a custom conversion to another class by implementing it explicitly using a static methods, for example, you can implement something like:
public class Cat : Animal
{
public Cat FromAnimal(Animal animal)
{
return new Cat(animal) {Eyes = Color.Blue, ... };
}
}
You can serialize and then deserialize your instance using certain serializers that support deserializing in another class.
You can Implement deep cloning of your instance with explicit return types of derived types.
Then you just substitute your old Animal
with a new-bord Cat
and use it everywhere...
Upvotes: 0
Reputation: 114
As far as I know you can't do that with a cast, but you could have a constructor in Dog that would accept and animal as a parameter like this:
Public Dog(Animal pAnimal)
{
//do stuff...
}
Upvotes: 0
Reputation: 351456
There is no way to do this without writing a custom conversion. Probably a better thing to do would be to decide much earlier what kind of derived type that you need and create an instance of that.
Most of the time when the type system is going to fight you in this way you need to redesign your architecture.
Upvotes: 1