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

Job*_*ian 0 c#

类---一

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

}
Run Code Online (Sandbox Code Playgroud)

类---乙

class ClassB:ClassA
{
    public string c2()
    {
        return "Class-B";
    }
}
Run Code Online (Sandbox Code Playgroud)

主类

- - -第1部分 - - - - - - - - -

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

- - -第2部分 - - - - - - - - -

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

在第1部分中,我将只得到c1.I需要知道是否为堆栈中的 ClassA创建变量(obj)并从Heap分配ClassB的地址.实际发生了什么?

在第2部分中,获取(编译错误)转换错误.执行此代码时屏幕后面实际发生了什么.

谢谢,Joby Kurian

Jon*_*eet 5

第1部分

ClassA obj1 = new ClassB();
Run Code Online (Sandbox Code Playgroud)

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

它还声明了一个名为type 的变量.该变量的始终是一个引用 - 或者是对实例的引用.在这种情况下,初始值是对新创建的对象的引用.(对象的引用也可以用作引用,因为派生自.)obj1ClassAnullClassAClassBClassBClassAClassBClassA

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

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

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

Eric Lippert在博客上发表了很多关于此类事情的博文.您可能希望从堆栈是一个实现细节开始.

第2部分

ClassB obj1 = new ClassA();
Run Code Online (Sandbox Code Playgroud)

这将创建一个实例ClassA,并尝试将对象的引用分配给类型的变量ClassB.这是不行的,因为ClassA不是从派生ClassB.您不能将编译时类型的引用用于类型ClassA的变量ClassB.为了说明为什么这不起作用,这有点像这样做:

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

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