【发布时间】:2017-02-14 11:30:32
【问题描述】:
查看 as 关键字在 C# 中的工作方式,我可以看到它允许在显式转换(即使用括号)阻止编译的地方进行转换。
但是,在下面的代码中,我发现如果我重写派生类中的方法,然后安全地转换为基类,派生类中的重写方法仍然会执行。为什么是这样?我希望执行基类中定义的方法。
class Base
{
public override string ToString()
{
return base.ToString();
}
public string OtherMethod()
{
return "Other method";
}
}
class Derived : Base
{
public override string ToString()
{
return "Derived class";
}
}
class Program
{
static void Main()
{
Derived d = new Derived();
Base b = new Base();
System.Console.WriteLine(b.ToString()); // Base
System.Console.WriteLine(d.ToString()); // Derived class
System.Console.WriteLine((d as Base).ToString()); // Derived class => WHY IS THIS?
System.Console.WriteLine((d as Base).OtherMethod()); // Other method
// System.Console.WriteLine((Base)d.OtherMethod()); // --- prevents compilation
// As noted in the comments, this works
System.Console.WriteLine(((Base)d).OtherMethod()); // Other method
System.Console.ReadLine();
}
}
【问题讨论】:
-
标记为“防止编译”的行并没有因为类型转换而失败。它失败了,因为您试图从
OtherMethod转换返回值。((Base)d).OtherMethod()应该编译得很好。 -
您正试图打破面向对象编程的多态特性。幸运的是你不能那样做,那会很糟糕。
-
它调用被覆盖的方法,因为该方法被覆盖。这就是重写方法的全部意义所在,以便调用它们而不是基方法。
-
“这是为什么?” as 运算符不会更改内存中对象的实际类型。它只是返回一个对该对象的引用(或者如果转换失败则返回一个空引用)。