我需要知道在执行以下代码时屏幕后面发生了什么

本文关键字:屏幕 代码 什么 发生了 执行 | 更新日期: 2023-09-27 18:30:40

Class---A

class ClassA
{
    public string c1()
    {
        return "Class-A";
    }
}

班级---B

class ClassB:ClassA
{
    public string c2()
    {
        return "Class-B";
    }
}

主类

-----第一部分------------------

 ClassA obj1 = new ClassB();
 string a = obj1.c1();//Here i will get only c1
 Console.WriteLine(a);
 Console.ReadLine();

-----第二部分------------------

 ClassB obj1 = new ClassA();
 string a = obj1.c2();//Her i will get both c1 and c2
 Console.WriteLine(a);
 Console.ReadLine();

在第 1 部分中,我将只得到 c1。我需要知道是否在堆栈中为 A类创建了变量 (obj),并从中分配了 B 类的地址。到底发生了什么?

在第-2部分中,获取(编译错误)转换错误。执行此代码时屏幕后面实际发生的情况。

谢谢乔比·库里安

我需要知道在执行以下代码时屏幕后面发生了什么

1 部分

ClassA obj1 = new ClassB();

这将创建ClassB实例 - 一个对象。

它还声明了一个名为 obj1变量,类型为 ClassA。该变量的值将始终是引用 - null或对ClassA实例的引用。在这种情况下,初始值是对新创建的ClassB对象的引用。(对ClassB对象的引用也可以用作ClassA引用,因为ClassB派生自ClassA

当你调用c1时,它只是在ClassA中调用实现 - 但在该方法中,如果你打印出this.GetType()它仍然会返回ClassB的类型,因为它在ClassB对象中"运行。

我强烈建议您不要担心堆栈和堆。专注于三个不同的概念

  • 对象
  • 引用(导航到对象的方式,或 null)
  • 变量(命名存储位置)

埃里克·利珀特(Eric Lippert)在博客上写了很多关于这类事情的文章。您可能希望从堆栈是实现细节开始。

第 2 部分

ClassB obj1 = new ClassA();

这将创建 ClassA 的实例,并尝试将对新对象的引用分配给类型为 ClassB 的变量。这是行不通的,因为ClassA不是ClassB派生出来的。不能将编译时类型 ClassA 的引用用于 ClassB 类型的变量。为了演示为什么这不起作用,这有点像这样做:

string x = new object();
Console.WriteLine(x.Length); // What could this possibly print out?

基本上,继承不是这样工作的 - 您可以将ClassB的实例视为ClassA的实例(在大多数情况下),但不能ClassA的实例视为ClassB的实例。您通常会在ClassB中添加更多的状态(字段),以便信息不会出现在ClassA的实例中。

发生的情况(在第二部分中)是你试图将类 A 实例化为类 B 的变量。无法执行此操作,因为变量必须具有可在实例化对象中访问的可用属性。因此,当您尝试调用方法 c2() 时,它在对象中不存在。反之则工作正常,因为变量的所有可用属性和方法都存在于实例化对象中。

正在创建类 A 的对象,并调用类 B 的构造函数创建该特定类伙伴的对象,然后访问属性。你为什么要对你感兴趣!