输入强制转换错误和构造函数

时间:2010-09-06 12:14:22

标签: c# .net casting static-typing

我有两个班级

 public class A
    {
        public A()
        {

        }
    }

    public class B:A
    {
        public B()
        {

        }
    }

以及Main中的代码如下

    A oa = new B();
    B ob = new A();

此处第1行成功编译,第2行显示类型转换错误。为什么会这样。调用new B()new A()时会发生什么?

2 个答案:

答案 0 :(得分:7)

您已声明了B类型的变量,然后尝试为其指定类型A的值。您已将B定义为某种A,但这并不意味着所有A都是B

这样想:

class Animal { }
class Dog : Animal { }
class Cat : Animal { }

你可以Animal rex = new Dog(),因为所有的狗都是动物,但不是Dog fido = new Animal(),因为并非所有的动物都是狗。

答案 1 :(得分:2)

  

新B()和   新的A()被调用?

  • new A()在堆上构造类型为A的对象,并返回对它的引用。

  • new B()在堆上构造类型为B的对象,并返回对它的引用。

  

这里第1行成功编译   第2行显示类型转换   错误。为什么会这样。

B子类A开始,它对类型A的引用有效,以引用运行时类型B的对象。毕竟,B只是A的“特殊情况”。

然而,相反的情况并非如此,因为并非所有A都可以被视为B。 虽然这是由C#的安全类型系统严格执行的,即使没有“真正的”不兼容性,但这种限制的原因是很自然的。例如,想象一下,B声明了一个属性public int Foo {get; set;}。 您如何期望这样做:

B ob = new A();
ob.Foo = 5;

这显然是不合逻辑的:引用引用的真实对象没有这样的属性。因此,编译器禁止这样的结构。

现在假设您将代码更改为:

B b = (B)new A();

在这里,您告诉编译器,在运行时创建的对象可以分配给类型为B的引用。这将编译正常,但由于断言明显不正确,将抛出运行时InvalidCastException

总结一下,C#的类型系统(如果你忽略dynamic和一些特殊情况)是静态安全:你将无法成功处理A的具体实例,就好像它是B类型一样。