无法将基类转换为派生类

Aut*_*erd 2 c# polymorphism casting

我有基类作为动物和儿童类作为狗

这是代码:

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

    public string Name  { get; set; }
}

class Dog : Animal
{
    public int noOfTail { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在我的主要方法中,当我在下面执行时,我得到异常:

   static void Main(string[] args)
    {
        Animal a = new Animal();
        Dog d = new Dog();
        d = (Dog)a;
    }
Run Code Online (Sandbox Code Playgroud)

但是当我第一次将我的派生类转换为父类时,我没有任何异常,这就是为什么我感到困惑,有人可以解释其背后的原因.

   static void Main(string[] args)
    {
        Animal a = new Animal();
        Dog d = new Dog();
        a = d;
        d = (Dog)a;
    }
Run Code Online (Sandbox Code Playgroud)

das*_*ght 5

Animal对象不能转换为Dog类型.一个Dog对象,而另一方面,可以转换为Dog即使你存储一个类型Dog对象的变量Animal类型.

在您的第一个示例中,您尝试强制转换AnimalDog失败,因为对象属于错误的类.在你的第二个例子中,你分配a = d,所以现在变量a有类型Animal,但它的运行时类型是Dog.这就是第二次演员的作品.

注意:这只是问题的技术部分,但也有一个逻辑组件:您的类层次结构允许您实例化Animal类,而不是叶类.

更好的方法是创建Animal一个接口或一个抽象类.通过这种方式,您只能实例化"实际"动物(Dog以及您希望从中获得的任何其他动物Animal),而在Animal不说它代表什么样的动物的情况下创建实例是不可能的.


Ali*_*ami 5

在案例二中,您有一个动物的实例

Animal a = new Animal();
Dog d = new Dog();
Run Code Online (Sandbox Code Playgroud)

然后,你reference copy动物

a = d;
Run Code Online (Sandbox Code Playgroud)

所以a指向d并且d是一个实例,并且像noOfTail这样的实例属性仍然存在但被隐藏并且在对象 a 中不可用。然后你有这条线:

d = (Dog)a;
Run Code Online (Sandbox Code Playgroud)

在最后一行中,您将d 的引用副本指向a,因此d指向a指向的位置,因此一切正常。

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

 Animal a = new Animal();
 Dog d = new Dog();
 d = (a as Dog); 
Run Code Online (Sandbox Code Playgroud)