当一个对象被强制转换为基类时,它如何记住它的真实含义?

Nic*_* R. 23 c# casting

这是初学者的问题,但我有兴趣了解这里发生了什么.我的问题是,当你向下投射一个物体时幕后会发生什么?它是否保留了关于它最初的内容的某种元数据?这就是我的意思:

假设我有一个名为"ClockIn"的方法,它接受"Employee"类型的参数:

public static void ClockIn(Employee employee)
{
   var manager = employee as Manager;
   if (manager != null)
   {
      manager.OpenSafe();
   }
}
Run Code Online (Sandbox Code Playgroud)

因此,假设Manager是Employee类型的子类,并且它具有"OpenSafe"方法:

public class Manager : Employee 
{
   public void OpenSafe()
   { 
      ... 
   }
}
Run Code Online (Sandbox Code Playgroud)

"ClockIn"方法,如果发现Manager已被传入,则调用OpenSafe方法.如:

var bob = new Manager();
ClockIn(bob);
Run Code Online (Sandbox Code Playgroud)

在这里,我将一个类型为Manager的实例传递给一个接受基类Employee的方法.在调用OpenSafe之前,我需要将ClockIn方法中的实例强制转换为Manager.

问题是,是否有一些元数据记得"bob"是一名经理,即使我已将他作为员工传递给他?代码如何知道他确实可以被投射到经理?堆中有什么东西在进行吗?

Gre*_*ill 13

首先要记住的是,转换根本不会改变原始对象.它只会通过该特定参考更改您对象的视图.多个引用可以指向同一个对象,因此更改对象对于转换是不合理的.

你可能在你的情况下做的就是让ClockIn()一个方法中的Employee类.然后,当你打电话

bob.ClockIn();
Run Code Online (Sandbox Code Playgroud)

然后bob就会知道他是什么类型真的是,并调用相应的ClockIn()他的类型的方法.这称为动态方法分派,不适用于static您的示例中的函数.

例如:

public class Employee {
    public void ClockIn() {
        ....
    }
}

public class Manager: Employee {
    public void ClockIn() {
        // first, do what all Employees do when clocking in
        Employee.ClockIn();
        // Next, do Manager specific actions
        OpenSafe();
    }
    public void OpenSafe() {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)

  • ClockIn也需要是虚拟的;) (3认同)

Pow*_*ord 5

强制转换不会更改对象的运行时类型.

GetType在对象上调用方法将返回Type表示其运行时类型的对象.