[英]How can I use a base type's methods, which return an object of the base type, in my derived type?
[英]How to change reference of Base object to Derived which was instatiated as Derived type
为什么我无法从Derived访问M3方法? Intellisense仅显示基类中的M1和M2。 如何将bc的参考从Base类型更改为Refernce Type,以便我可以访问M3方法。
class Program
{
static void Main(string[] args)
{
Base bc = new Derived();
bc.M3():// error
}
}
class Base
{
public void M1()
{
Console.WriteLine("M1 from BASE.");
}
public void M2()
{
Console.WriteLine("M2 from BASE.");
}
}
class Derived : Base
{
public void M3()
{
Console.WriteLine("M3 from DERIVED.");
}
}
编译器必须在编译时解析名称M3
。 这是在Base
类型的引用上调用的, Base
没有该名称的成员。 事实上它恰好指向运行时的Derived
实例,因为编译器正在查看编译时可用的信息。
是的,在这种特定情况下,编译器可以看到bc
始终初始化为Derived
值,因此它应该在那里看。 然而,这不是c#编译器的工作原理。 它仅查看所涉及引用的编译时类型
因为您将您的类型转换为基类,所以所有可用成员的集合将减少为Base
可用的成员集。
Derived bc = new Derived();
bc.M3():// CORRECT
或者干脆
var bc = new Derived();
bc.M3():// CORRECT
如果您需要在应用程序中使用Base
class for polymorphism并且需要使用M3()
考虑在Base
类中移动它
因为bc
引用唯一的保证是它将引用Base
的实例或从Base
派生的东西。
考虑代码是否改变如下:
Base bc = new Derived();
if(DateTime.DayOfWeek == DayOfWeek.Sunday)
{
bc = new Base();
}
bc.M3();
这是完全合法的,因为bc
的保证仍然是满满的。
有两种方法可以解决这个问题:转换和多态。
转换意味着您告诉编译器您知道这确实是Derived
实例,即使引用是Base
类型。
Base bc = new Derived();
if(bc is Derived)
{
((Derived)bc).M3();
}
另一种是在基类中声明M3函数,然后在派生类中重写它
class Base
{
// Other stuff...
public virtual void M3()
{
}
}
class Derived : Base
{
public override void M3()
{
Console.WriteLine("M3 from DERIVED.");
}
}
正如其他人所说, bc
被宣布为Base
类型。 你需要先抛出它
Base bc = new Derived();
((Derived)bc).M3()
如果bc
实际上是Base
类型而不是Derived
那么这将是一个运行时错误。
这是因为编译器只看到您正在使用Base类型的变量。
请使用以下代码:
Base bc = null;
if (SomeValue)
{
bc = new Base();
}
else
{
bc = new Derived();
}
SomeValue的值可以在运行时变化。 这意味着编译器在编译时不会知道bc
的实际类型。 这是基类的全部概念。 您与基类共享相同的接口,但您可以更改方法的实现。
但是,您可以将类型转换为其他类型:
Derived dc = bc as Derived;
if ( dc != null ) // cast succeeded so we have a Derived
{
dc.M3();
}
要只检查一个类型是另一种类型的可以使用的is
: if (dc is Derived)
。
但请注意这样做的危险。 这样,您就会使用所有类型特定的检查来乱丢代码,这使得它更难理解和维护。 如果您想了解更多有关此内容的信息,请阅读S OLID模式 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.