The visitor pattern is a mechanism to simulate dual binding in programming languages that only support single binding. Unfortunately, that statement might not clarify things a lot, so let me explain with a simple example.
In .NET and C#, the platform you are using, objects can be converted to strings using the
ToString() function. What that funtion does, i.e. the code being executed, depends on the type of object you're applying it to (it's a virtual method). What code is executed depends on one thing, the one type of the object, hence the mechanism used is called single binding.
But what if I want to have more than one way to convert an object to a string, for each different kind of object? What if I wanted to have two ways to convert objects to strings, so that the code being executed depends on two things: not only the object to be converted, but also the way in which we want it to be converted?
That could be solved nicely if we had dual binding. But most OO languages, including C#, only support single binding.
The visitor pattern solves the problem, by turning dual binding into two succesive single bindings.
In our example above, it would use a virtual method in the object to convert, that calls a second virtual method in the object implementing the conversion algorithm.
But that implies that the object upon which you want to apply the algorithm needs to collaborate with this: it needs to have support for the visitor pattern baked in.
You seem to be using .NET's Windows Forms classes, which do not have support for the visitor pattern. More specifically, they would need to have a
public virtual void Accept(IVisitor) method, which obviously they don't have.
So, what's the alternative? Well, .NET does not only support single binding, it also supports dynamic binding, which is even more peowerful than dual binding.
For more information on how to apply that technique, which will allow you to solve your problem (if I understand it well), take a look at Farewell Visitor.
To apply the technique to your specific problem, first define your extension method:
public static XmlDocument ToXml(this Control control)
XmlDocument xml = new XmlDocument();
XmlElement root = xml.CreateElement(control.GetType().Name);
Visit(control, xml, root);
Create the dynamic dispatcher:
private static void Visit(Control control, XmlDocument xml, XmlElement root)
dynamic dynamicControl = control; //notice the 'dynamic' type.
//this is the key to dynamic dispatch
VisitCore(dynamicControl, xml, root);
Then fill in the specific methods:
private static void VisitCore(Control control, XmlDocument xml, XmlElement root)
// TODO: specific Control handling
private static void VisitCore(ContainerControl control, XmlDocument xml, XmlElement root)
// call the "base" method
VisitCore(control as Control, xml, root);
// TODO: specific ContainerControl handling
// for example:
foreach (Control child in control.Controls)
XmlElement element = xml.CreateElement(child.GetType().Name);
// call the dynamic dispatcher method
Visit(child, xml, element);
private static void VisitCore(Form control, XmlDocument xml, XmlElement root)
// call the "base" method
VisitCore(control as ContainerControl, xml, root);
// TODO: specific Form handling