C# 2.0 - Visitor return type

In this entry I'm revisting the Visitor Pattern, this time using C# 2.0 generics rather than Java generics. One addition to the previous design is to declare two interaces, one for a void return and one for a non-void return:
public interface IVisitable
{
    void Accept(IVisitor visitor);
    R    Accept(IVisitor1<R> visitor);
}
public interface IVisitor
{
    void Visit(A visited);
    void Visit(B visited);
    void Visit(C visited);
}
public interface IVisitor1<R>
{
    R Visit<R>(A visited);
    R Visit<R>(B visited);
    R Visit<R>(C visited);
}
Each concrete element then simply implements both Accept methods:
public class A : IVisitable
{
    ...
    public void Accept(Visitor visitor)
    {
       visitor.Visit(this);
    }
    public R Accept<R>(Visitor1<R> visitor)
    {
        return visitor.Visit(this);
    }
    ...
}
I could do this in Java too of course. However, the C# version edges out the Java version in two respects. First, C# allows two types to have the same name as long as they have a different number of generic arguments.
public interface IVisitor
{
    void Visit(A visited);
    void Visit(B visited);
    void Visit(C visited);
}
public interface IVisitor<R>
{
    R Visit<R>(A visited);
    R Visit<R>(B visited);
    R Visit<R>(C visited);
}
Secondly, generic IVisitor works with all types (including value types such as bool) without the need for wrapper classes:
public class ExampleVisitor : IVisitor<bool>
{
    public bool Visit(A visited) { ... }
    public bool Visit(B visited) { ... }
    public bool Visit(C visited) { ... }
}

1 comment:

  1. This comment has been removed by a blog administrator.

    ReplyDelete