Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 铸态后的对象类型?_C#_Casting - Fatal编程技术网

C# 铸态后的对象类型?

C# 铸态后的对象类型?,c#,casting,C#,Casting,鉴于该代码: class B { public virtual string Method() { return "base"; } } class D : B { public override string Method() { return "derived"; } } D d = new D(); B b = d as B; b.Method(); “派生”是输出 但究竟为什么呢? 我的意思是,b是一个b型的新对象,不是吗?或者它和d是同

鉴于该代码:

class B
{
  public virtual string Method()
  {
     return "base";
  }
}

class D : B
{
  public override string Method()
  {
     return "derived";
  }
}

D d = new D();
B b = d as B;
b.Method();
“派生”是输出

但究竟为什么呢? 我的意思是,b是一个b型的新对象,不是吗?或者它和d是同一个对象(在内存中)?如果是,那么b的运行时类型是什么,b还是D


谢谢

规则很简单:
b
是对
D
类型的对象的引用。您可以说
b
的运行时类型是
D
,但这不是特别有用的术语

b是类型b的新对象,不是吗

否,
b
是类型为
b
的现有对象,它指向您在其正上方创建的相同对象:
d
。唯一的区别是您已将对象强制转换为其父类型--
B
,因此
B
被视为
B
,而不是更派生的类型
D

获得“派生”输出的原因是,该方法在派生类中被重写,这就是重写的工作方式。仅仅因为您将一个变量(即
b
)声明为其派生较少的类型
b
,并不意味着它实际上仍然不是派生较多的类型
D
。这就是多态性的本质。

你可以这样做

B b = new D();
b.Method();
你仍然会得到“派生的”。正如@Bathsheba所提到的,重要的是对象类型而不是引用

想象一个典型的OOP示例,其中您有一个基类
Shape
,派生类
Circle
Square
,等等,使用虚拟方法
Area
。。如果您有这样的方法:

void ShowArea(Shape shape)
{
    Console.WriteLine(shape.Area());
}
参考不重要(而是实际对象类型)这一事实使类似上述的方法能够接受任何类型的
形状
,并且仍然打印正确的区域

B b = d as B;

我相信这行代码只将d转换为类B的类型,但值仍然是“派生的”。

B
具有类型
B
,但指向与类型
d
相同的对象。运行时类型也是
D
。不要与方法隐藏混淆。i、 e.
new
关键字。如果您使用new重新安装覆盖,它将实际打印
“base”
。这称为运行时多态性