类型转换错误和构造函数

发布于 2024-09-18 01:10:42 字数 375 浏览 9 评论 0原文

我有两个类

 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

So尛奶瓶 2024-09-25 01:10:42

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

可以这样想:

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

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

You have declared a variable of type B, and then attempted to assign a value of type A to it. You have defined B to be a kind of A, but that doesn't mean that all A's are B's.

Think of it like this:

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

You can do Animal rex = new Dog(), because all dogs are animals, but not Dog fido = new Animal(), because not all animals are dogs.

你穿错了嫁妆 2024-09-25 01:10:42

当 new B() 和
new A() 被调用吗?

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

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

这里第1行编译成功
而第 2 行显示类型转换
错误。为什么会发生这种情况。

由于 BA 的子类,因此 A 类型的引用引用运行时类型 B< 的对象是有效的/代码>。毕竟,B 只是 A 的“特例”。

然而,反之则不然,因为并非所有 A 都可以被视为 B
尽管即使不存在“真正的”不兼容性,C# 的安全类型系统也严格执行这一点,但此类限制的原因是很自然的。例如,假设 B 声明了一个属性 public int Foo {get;设置;}
您期望它的行为如何:

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

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

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

B b = (B)new A();

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

总而言之,C# 的类型系统(如果您忽略动态和一些特殊情况)既是静态安全:您将无法成功将 A 的具体实例视为 B 类型。

What exactly happens when new B() and
new A() gets called?

  • new A() constructs an object of type A on the heap and returns a reference to it.

  • new B() constructs an object of type B on the heap and returns a reference to it.

Here line 1 compiles successfully
while line 2 displays typecasting
error. Why this happens.

Since B subclasses A, it is valid for a reference of type A to refer to an object of run-time type B. After all, B is simply a "special case" of A.

However, the converse is not true, because not all As can be considered Bs.
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 property public int Foo {get; set;}.
How would you expect this to behave:

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

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-time InvalidCastException 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 of A as though it were of type B.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文