我需要“this”关键字和继承方面的帮助

时间:2017-03-30 23:50:34

标签: c# inheritance this abstract-class virtual-functions

abstract class BaseClass
{
    public virtual void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }
}

class DerivedClass: BaseClass
{
}

interface IVisitor
{
    void Visit(BaseClass baseEntity);
    void Visit(DerivedClass derivedEntity);
}

class Visitor : IVisitor
{
    public void Visit(DerivedClass derivedEntity)
    {
        Debug.WriteLine("Derived Entity visited");
    }

    public void Visit(BaseClass baseEntity)
    {
        Debug.WriteLine("Base Entity visited");
    }
}

在上述判决之后

class Program
{
    static void Main(string[] args)
    {
        DerivedClass derived = new DerivedClass();
        Visitor visitor = new Visitor();
        derived.Accept(visitor);
    }
}

产生

"Base Entity visited"

然而我希望它能产生

"Derived Entity visited"
  • 任何人都可以解释原因吗?
  • 我应该怎么做才能制作“已访问的衍生实体”?我不想覆盖“接受”功能。

2 个答案:

答案 0 :(得分:2)

在编译时解决了重载,因此在编译BaseClass时,编译器将选择与其编译时类型(Visitor.Visit)匹配的BaseClass重载。

使用访问者模式时,通常需要覆盖派生类中的Accept方法。

虽然您可以使用dynamic来避免这种情况,但如果您这样做,则会失去静态类型检查的优势。

This article显示了C#中访问者模式的示例,其中Accept方法在派生类中被覆盖。

答案 1 :(得分:1)

您面临的问题是多次调度。编译器选择基类,因为您是从基类调用它。您可以添加的一个快速解决方案是使用dynamic

public virtual void Accept(IVisitor visitor)
{
    visitor.Visit(this as dynamic);
}

您欺骗编译器不知道对象的实际类型 - 并调用正确的访问重载。

以下是MSND

的额外阅读