AutomationNerd
AutomationNerd

Reputation: 486

Unable to cast base class to derived class

I have base class as Animal and child class as Dog

Here is the code:

class Animal
{
    public int Legs { get; set; }

    public string Name  { get; set; }
}

class Dog : Animal
{
    public int noOfTail { get; set; }
}

In My Main Method when I execute below I get the exception:

   static void Main(string[] args)
    {
        Animal a = new Animal();
        Dog d = new Dog();
        d = (Dog)a;
    }

but when I first cast my derived class to parent I don't get any exception, and that is why I am confused, can somebody explain reason behind it.

   static void Main(string[] args)
    {
        Animal a = new Animal();
        Dog d = new Dog();
        a = d;
        d = (Dog)a;
    }

Upvotes: 12

Views: 18406

Answers (7)

hossein sedighian
hossein sedighian

Reputation: 2063

the reason you can not do this is the Reference

in some other ways you can do that Create A Mapping

var a = new Animal();
var b = new Dog { name = a.name }

Create something like this

var a = new Animal();
var b = JsonSerializer.Deserialize<Dog>(JsonSerializer.Serialize(a));
               

Upvotes: 0

sajid irfan
sajid irfan

Reputation: 387

If you want to convert, simple approach is to just serialize and deserialize it using json.

JsonConvert.DeserializeObject<ChildClass>(JsonConvert.SerializeObject(baseObject))

Upvotes: 1

James
James

Reputation: 290

Animal is not a Dog. Dog is an Animal. This is why you cannot cast an Animal to a Dog in the first example.

In the second example it works because Animal has been assigned the value of Dog. When you assigned a = d the Animal became a Dog.

Upvotes: 2

Ali Sheikh Nezami
Ali Sheikh Nezami

Reputation: 172

In Case two you have an instance of dog and animal

Animal a = new Animal();
Dog d = new Dog();

Then you have reference copy of dog to animal

a = d;

So the a is points to d and d is a dog instance and instance properties like noOfTail is still exist but is hidden and not available in object a. and then you have this line :

d = (Dog)a;

In last line you have reference copy of d to a ,so d is point to where a is point to so everything is okay.

but in case one you want copy one Instance of child class Dog to an instance of Animal so the properties of child class will be lost. you need to confirm that with Compiler and say to him you know instance properties like noOfTail will not be available any more your code most be like this :

 Animal a = new Animal();
 Dog d = new Dog();
 d = (a as Dog); 

Upvotes: 7

Hameed Syed
Hameed Syed

Reputation: 4275

Animal a = new Animal();
Dog d = new Dog();
d = (Dog)a;

So to summary up wrt to Animal and Dog class, we can state that an object to become an animal it must possess legs and name property and an object to become dog it must have nooftails property in addition to name and legs property.

Lets simplify by giving each object's properties explicit values.

Animal a = new Animal();
a.Name="Monkey";
a.Legs=2;
Dog d = new Dog();
a.Name="Dog";
a.Legs=4;
a.noOfTail=1;

Assume below statement doesn't throw any compiler error.

 d = (Dog)a;

What does it mean? Legs and name which is a monkey object you are trying to make or transform or cast the monkey object as a dog without noOftails property, it's nooftails property which uniquely identifies or differentiates the Base Animal from derived Dog class which defeats the basic purpose of Inheritance.

Hence compiler prevents you from making such absurd cast.

Upvotes: 1

Jonathan Applebaum
Jonathan Applebaum

Reputation: 5986

You cannot cast a base class to a derived class, but you can do the opposite: cast a derived class to a base class.

Your second attempt works for a very simple reason: a = d; => you are assigning a derived class instance to a base class instance.
that OOP fundamental is called polymorphism.

static void Main(string[] args)
    {
        Animal a = new Animal();
        Dog d = new Dog();
        a = d; // you can do that but you cant do d=a
        d = (Dog)a;
    }

To understand it better try to delve into that piece of code:

public void polymorphism()
{
    // thats wrong and the compiler will throw an exception (at design time) because animal is not a dog
    Dog d = new Animal();
    // thats correct becasue dog is an animal
    Animal a = new Dog();
}

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727047

Animal object cannot be cast to a Dog type. A Dog object, on the other hand, can be cast to Dog type even if you store a Dog object in a variable of Animal type.

In your first example you attempt to cast an Animal to Dog, which fails, because object is of a wrong class. In your second example you assign a = d, so now variable a has type Animal, but its runtime type is Dog. That is why the second cast works.

Note: This is only the technical part of your problem, but there is also a logical component to it: your class hierarchy lets you instantiate Animal class, which is not a leaf class.

A better approach would be to make Animal an interface or an abstract class. This way you would be able to instantiate only the "actual" animals (Dog and whatever else you wish to derive from Animal), while it would not be possible to create an instance of Animal without saying what kind of animal it represents.

Upvotes: 7

Related Questions