Unable to cast base class to derived class

时间:2018-02-03 10:40:16

标签: c# casting polymorphism

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;
    }

5 个答案:

答案 0 :(得分:5)

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.

答案 1 :(得分:2)

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();
}

答案 2 :(得分:1)

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.

答案 3 :(得分:1)

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.

答案 4 :(得分:1)

在案例二中,你有一个 dog animal 的实例

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

然后你有{em>狗的reference copy动物

a = d;

所以 a 指向 d d dog 实例和实例属性如 noOfTail 仍然存在但隐藏在对象a中不可用。 然后你有这一行:

d = (Dog)a;

在最后一行中,您将 d 的引用副本复制到 a ,因此 d 指向 a 的位置是的,所以一切都好。

但是如果您希望将一个Instance of child class Dog 复制到 Animal 的实例,那么子类的属性将会丢失。您需要通过Compiler确认并告诉他您知道noOfTail之类的实例属性将不再可用 你的代码最像这样:

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