【问题标题】:Type casting error and constructor类型转换错误和构造函数
【发布时间】:2010-09-06 12:14:22
【问题描述】:
我有两节课
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() 被调用时会发生什么?
【问题讨论】:
标签:
c#
.net
casting
static-typing
【解决方案1】:
您已经声明了一个B 类型的变量,然后尝试为其分配一个A 类型的值。您已将B 定义为A 的一种,但这并不意味着所有A 都是B 的。
这样想:
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
你可以Animal rex = new Dog(),因为所有的狗都是动物,但不是Dog fido = new Animal(),因为不是所有的动物都是狗。
【解决方案2】:
当 new B() 和
new A() 被调用?
这里第1行编译成功
而第 2 行显示类型转换
错误。为什么会这样。
由于B 是A 的子类,因此A 类型的引用可以引用运行时类型B 的对象。毕竟B只是A的“特例”。
然而,反之则不然,因为不是所有的As 都可以被认为是Bs。
尽管这由 C# 的 safe 类型系统严格执行,即使没有“真正的”不兼容,但这种限制的原因是自然的。例如,想象一下B 声明了一个属性public int Foo {get; set;}。
您希望它的表现如何:
B ob = new A();
ob.Foo = 5;
这显然是不合逻辑的:引用所指的 real 对象没有这样的属性。因此,编译器禁止此类构造。
现在假设您将代码更改为:
B b = (B)new A();
在这里,您告诉编译器创建的对象将在运行时分配给B 类型的引用。这将编译得很好,但由于断言显然不正确,因此将抛出运行时InvalidCastException。
总而言之,C# 的类型系统(如果您忽略 dynamic 和一些特殊情况)既是 static 又是 safe:您将无法成功处理A 的具体实例,就好像它是 B 类型一样。