Upcasting如何保留派生类的属性?

时间:2017-09-08 11:50:51

标签: c# casting boxing

newstudent.LastName

我想知道Iregister如何获得正确的值,因为它是从没有LastName属性的student.LastName投放的? 价值如何" Shekar"从newstudent.LastName传递到xvar isempty: boolean; ::thread x if not isempty then begin .... isempty := true; end; ... ::thread y isempty := false: 将它存储在介于两者之间的位置吗?如果我错过了一些基础知识,请原谅我。

4 个答案:

答案 0 :(得分:4)

您创建一个对象,并在变量student中为其指定引用。

然后,您为同一对象创建第二个引用,并将其分配给xxstudent都指向同一个对象,但x变量的类型意味着只有IRegister上定义的成员可用。

然后,您创建对同一对象的第三个引用,并将其分配给newstudent。由于newstudent的类型为Student,因此您可以从该引用中访问Student的所有成员。

并非变量只存储引用。它是存储自己的实际数据的对象,并且该对象在整个过程中保持不变。

答案 1 :(得分:3)

  

我想知道newstudent.LastName是如何得到正确值的   是从没有LastName属性的Iregister生成的?

事实是,xIregister类型,但它指向Student对象,因此一旦投放了你能够访问Student字段。

答案 2 :(得分:1)

直接使用x时,编译器允许您仅选择IRegister类型上定义的成员,因为x属于该类型。将x转换为Student后,编译器允许您使用Student的任何成员,因为newstudent变量的类型为Student

答案 3 :(得分:1)

  

Interface如何存储继承的类的属性

接口没有存储值。它们仅确保实现接口的类中某些属性和方法的可用性。

  

我想知道newstudent.LastName如何获得正确的值,因为它是从没有Iregister属性的LastName投放的?

向下转换对象不会更改对象的类型,它只会更改您正在使用的变量的类型。

public interface IMyInterface
{
    String Name { get; }
}

public class BaseType : IMyInterface
{
    public virtual String Name
    {
        get { return "Base Name"; }
    }
}

public class DerivedType : BaseType
{
    public override String Name
    {
        get { return "Derived Name"; }
    }
}

然后,我在C#Interactive窗口中测试了以下命令:

var derived = new DerivedType();

IMyInterface derivedAsInterface = derived;
BaseType derivedAsBaseType = derived;

derived.Name                //returns "Derived Name"
derivedAsInterface.Name     //returns "Derived Name"
derivedAsBaseType.Name      //returns "Derived Name"

正如您所看到的,每当您要求Name属性时,对象仍然表现为DerivedType,因为这就是对象。

这是因为类本质上是引用类型。这对值类型(例如floatint)的工作方式不同,但这与值和引用类型之间的固有差异有关。
如果您想知道原因,请阅读the difference between value and reference types in C#

如果你考虑一下,你的假设没有意义。在我的代码示例中,我有三个单独的变量:derivedderivedAsInterfacederivedAsBaseType。这些都指向内存中的相同对象。

这在逻辑上意味着同一个对象必须与所有三个变量兼容,否则在你想要的时候就不可能使用所有这些变量。

  • 如果对象已更改为IMyInterface类型的对象,则我的变量derivedAsBaseTypederived将无法正常运行。
  • 如果对象已更改为BaseType类型的对象,则我的变量derived将无法正常运行。
  • 唯一剩下的解释是我的对象始终保持其原始类型(DerivedType),因为这是保持与所有三个变量兼容的唯一方式。

如果你不理解为什么他们在内存中引用同一个对象,你应该阅读the difference between value and reference types in C#。对于StackOverflow上的答案,此主题过于宽泛。