类型转换错误和构造函数
我有两个类
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()
被调用时到底会发生什么?
I have two classes
public class A
{
public A()
{
}
}
public class B:A
{
public B()
{
}
}
and it the code in Main is as follows
A oa = new B();
B ob = new A();
Here line 1 compiles successfully while line 2 displays typecasting error. Why this happens. What exactly happens when new B()
and new A()
gets called?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您已声明一个
B
类型的变量,然后尝试为其分配一个A
类型的值。您已将B
定义为A
的一种,但这并不意味着所有A
都是B的。
可以这样想:
您可以执行
Animal rex = new Dog()
,因为所有狗都是动物,但不能执行Dog fido = new Animal()
,因为并非所有狗都是动物动物是狗。You have declared a variable of type
B
, and then attempted to assign a value of typeA
to it. You have definedB
to be a kind ofA
, but that doesn't mean that allA
's areB
's.Think of it like this:
You can do
Animal rex = new Dog()
, because all dogs are animals, but notDog fido = new Animal()
, because not all animals are dogs.new A()
在堆上构造一个A
类型的对象并返回对其的引用。new B()
在堆上构造一个B
类型的对象并返回对其的引用。由于
B
是A
的子类,因此A
类型的引用引用运行时类型B< 的对象是有效的/代码>。毕竟,
B
只是A
的“特例”。然而,反之则不然,因为并非所有
A
都可以被视为B
。尽管即使不存在“真正的”不兼容性,C# 的安全类型系统也严格执行这一点,但此类限制的原因是很自然的。例如,假设
B
声明了一个属性public int Foo {get;设置;}
。您期望它的行为如何:
这显然是不合逻辑的:引用所引用的真实对象没有这样的属性。因此,编译器禁止此类构造。
现在假设您将代码更改为:
B b = (B)new A();
在这里,您告诉编译器创建的对象将在运行时,可分配给
B
类型的引用。这可以很好地编译,但由于断言显然不正确,因此将抛出运行时InvalidCastException
。总而言之,C# 的类型系统(如果您忽略
动态
和一些特殊情况)既是静态又安全:您将无法成功将A
的具体实例视为B
类型。new A()
constructs an object of typeA
on the heap and returns a reference to it.new B()
constructs an object of typeB
on the heap and returns a reference to it.Since
B
subclassesA
, it is valid for a reference of typeA
to refer to an object of run-time typeB
. After all,B
is simply a "special case" ofA
.However, the converse is not true, because not all
A
s can be consideredB
s.Although this is strictly enforced by C#'s safe type-system even if there is no "real" incompatibility, the reasons for such restrictions are natural. Imagine, for example, that
B
declared a propertypublic int Foo {get; set;}
.How would you expect this to behave:
This is clearly illogical: the real object that the reference is referring to has no such property. Consequently, the compiler prohibits such constructs.
Now imagine you changed your code to:
B b = (B)new A();
Here, you are telling the compiler that the object created, will, at run-time, be assignable to a reference of type
B
. This will compile fine, but since the assertion is clearly incorrect, a run-timeInvalidCastException
will be thrown.To summarize, C#'s type system (if you ignore
dynamic
and a few special cases) is both static and safe: you will not successfully be able to treat a concrete instance ofA
as though it were of typeB
.