« Assemblies EmbeddedResources with .NET 3.5 SP1Article on Tech Head Brothers »

7 comments

Comment from: Jonathan [Visitor] · http://www.jonathancrossland.com
Hi

Nice idea.
Why not add it to http://www.extensionmethod.net/

Best Wishes
Jonathan
03/26/09 @ 12:04
Comment from: Nicolas Penin [Member] Email · http://dragon-angel.fr
Hello,

Because I did not know this web site ;)

Will do it as soon as I have time.

Thanks for the idea

Nicolas
03/26/09 @ 12:07
Comment from: Trent Kerin [Visitor]
Hi there

I'm not entirely sure how the generic visitor works.

As I understand it, the visitor pattern is used when code needs to behave differently based on the specific type of a method argument, but only the base type is known at compile time.

If the compiler is able to use type inference to determine the specific type of an argument and call the appropriately-typed generic extension method then the programmer also knows it and therefore doesn't need the visitor pattern.

If the compiler only knows the base type, then so will the extension method, and it will only call the base type version of the Visit method, and the visitor has failed.

I made a quick implementation of the above and found my concerns verified, but it's entirely possible I screwed something up. Could you please correct my code below if that's the case; it'd be great to have a generic visitor :>

To use the visitor:

SomeVisitor visitor = new SomeVisitor();
SomeBaseClass visitable = new SubClassOne();
visitable.Accept(visitor);


And here's the visitor code itself:

public class SomeBaseClass
{
}

public class SubClassOne : SomeBaseClass
{
}

public static class ExtensionClass
{
public static void Accept(this T visitable, V visitor)
where V : IVisitor
{
visitor.Visit(visitable);
}
}

public class SomeVisitor : IVisitor
{
public void Visit(SomeBaseClass visitable)
{
throw new Exception("The visitor didn't work!");
}

public void Visit(SubClassOne visitable)
{
throw new Exception("The visitor did work. Hooray!");
}
}

public interface IVisitor
{
void Visit(T visitable);
}



Thoughts?

-Trent
04/13/09 @ 04:17
Comment from: Nicolas Penin [Member] Email · http://dragon-angel.fr
Hello Trent,

thanks for paying attention to my post. What you missed is the IVisitor which says : "I can visit this type", therefore, the choose of the right method is made thanks to type inference and polymorphism. You need this Accept method to be generic and your visitor to have all implementations for each Visit(T item) you need (even the subclasses).

Hope this helps.

Nicolas
04/13/09 @ 10:45
Comment from: Trent Kerin [Visitor]
Hi Nicolas

Thanks for the quick reply. I've still got a few issues:

1) Sorry, the extension method I implemented was actually generic, but the comment system stripped the generic T,V parameters from the Accept method. Could you point out exactly what I'd need to change in my code above to make it an appropriate concrete example of the functionality your post is describing?

2) Type inference is only helpful when we're passing an argument cast to its most-specific runtime type. The visitor pattern is for the situation where our argument is cast as a base-type, and we want to deal with it as its specific type (without having some if-then-else or switch block).

3) I'm not sure how polymorphism helps either. Extension methods are static and static methods can't be polymorphic since you call them on the declaring type (or via some syntactic sugar in the case of extension methods). So which other thing are you saying is being dealt with polymorphically? The visitable object? The visitor?

-Trent
04/13/09 @ 14:16
Comment from: Nicolas Penin [Member] Email · http://dragon-angel.fr
Hello,

You're entirely right. What I forgot, is that I used this visitor system for a Linq provider which has to deal with an ExpressionType which is an enum. What you could do is implementing an IVisitable interface on your subclasses. Thus, you would have the Accept method implemented directly in your class. An implemented method having a higher priority than an extension method it should work. But I agree with you, the best thing would be to have type inference working directly...
04/14/09 @ 09:02
Comment from: Trent Kerin [Visitor]
OK, so if the visitable objects are going to implement their own Accept methods, then it seems the extension method Accept doesn't serve any purpose. Correct?

If so: Your post doesn't currently implement the visitor pattern. To change it so it does implement the visitor pattern would obsolete the extension method Accept, and thereby remove C# 3.0 features.

It seems like your post needs to be edited so that inexperienced readers don't get misled into thinking they can do something which they actually can't. Equally bad, an inexperienced reader might become confused about what the visitor pattern is actually for. I highly recommend a concrete example, rather than just a snippet of code and some optimistic words.

Barring some amazing discovery, the most reasonable implementation of the visitor pattern has remained unchanged since C# 1.0. Following is a post that shows some real progress on the visitor, in C# 4.0:

http://www.paulbatum.com/2008/11/no-visitors.html
04/14/09 @ 23:43

Comments are closed for this post.