I need help with the "this" keyword and inheritance
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");
}
}
Following the above declerations
class Program
{
static void Main(string[] args)
{
DerivedClass derived = new DerivedClass();
Visitor visitor = new Visitor();
derived.Accept(visitor);
}
}
produces
"Base Entity visited"
however I expect it to produce
"Derived Entity visited"
- Can anyone explain why?
- What should I do to create a "Derived Entity visited"? I don't want to override the Accept function.
source to share
The problem you are having is with multiple dispatchers. The compiler picks the base class because you are calling it from the base class. One quick solution you can add is to use dynamic
:
public virtual void Accept(IVisitor visitor)
{
visitor.Visit(this as dynamic);
}
You are tricking the compiler into not knowing the actual type of the object, and you are calling the correct visit overload.
And here is some additional reading from MSND
source to share
Overloads are resolved at compile time, so when you compile, your BaseClass
compiler is going to choose the overload Visitor.Visit
that matches the compile-time ( BaseClass
) type.
When using the Visitor pattern, you usually need to override the method Accept
in derived classes.
As long as you can avoid it by using dynamic
, you will lose the benefit of static type checking if you do.
This article shows an example of a C # visitor pattern where the method is Accept
overridden in derived classes.
source to share