我有两个课

 public class A
    {
        public A()
        {

        }
    }

    public class B:A
    {
        public B()
        {

        }
    }

它的主要代码如下

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

在此处,第1行成功编译时,当第2行显示打字错误。为什么会发生这种情况。到底会发生什么 new B()new A() 被打电话?

有帮助吗?

解决方案

当新的B()和New A()被调用时,到底会发生什么?

  • new A() 构建类型的对象 A 在堆上返回对其的引用。

  • new B() 构建类型的对象 B 在堆上返回对其的引用。

在此处,第1行成功编译时,当第2行显示打字错误。为什么会发生这种情况。

自从 B 子类 A, ,对于类型的引用是有效的 A 引用运行时类型的对象 B. 。毕竟, B 只是一个“特殊情况” A.

但是,匡威不是真的,因为不是全部 A可以考虑 Bs。虽然这是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.

其他提示

您已经声明了类型的变量 B, ,然后尝试分配类型的值 A 对此。您已经定义了 B 成为一种 A, ,但这并不意味着全部 AB'

这样想:

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top