I have a model, deserialized from XML, in which all node objects derive from the same base class, and nodes can be nested (somewhat) arbitrarily. I am trying to write a collection of modules which can translate a loaded model into various text based formats. I thought it would be nifty if each such module was an extension class which would allow me to simply call Model.ToText(), Model.ToHtml(), etc. But I am running into some problems.
Here is a simplified example:
using System;
using System.Collections.Generic;
using System.Text;
namespace Sample
{
public abstract class Foo
{
}
public class Bar : Foo
{
public List<Foo> Children = new List<Foo>();
public int Qux;
}
public class Baz : Foo
{
public string Quux;
}
public static class Extension
{
public static string ToText(this Foo foo, int indent = 0)
{
return String.Format("{0}Foo <>\n", new String(' ', indent));
}
public static string ToText(this Bar bar, int indent=0)
{
StringBuilder sb = new StringBuilder();
sb.Append(String.Format("{0}Bar <Qux={1}>\n", new String(' ', indent), bar.Qux));
foreach (var child in bar.Children)
{
sb.Append(child.ToText(indent + 1));
}
return sb.ToString();
}
public static string ToText(this Baz baz, int indent=0)
{
return String.Format("{0}Baz <Quux={1}>\n", new String(' ', indent), baz.Quux);
}
}
class Program
{
static void Main(string[] args)
{
Baz baz = new Baz { Quux = "frob" };
Bar bar = new Bar
{
Children = new List<Foo>()
{
new Baz {Quux = "fred"},
new Bar
{
Qux = 11,
Children = new List<Foo>()
{
new Baz() {Quux = "flog"}
}
}
}
};
//This works
Console.WriteLine(baz.ToText());
//But this doesn't
Console.WriteLine(bar.ToText());
Console.ReadKey();
}
}
}
If I run this I get:
Baz <Quux=frob>
Bar <Qux=0>
Foo <>
Foo <>
If I try and get tricky and do this instead:
public static string ToText(this Foo foo, int indent = 0)
{
return ((dynamic)foo).ToText(indent);
}
... the first print works, but the second gives me the exception:
{"'Sample.Baz' does not contain a definition for 'ToText'"}
I am probably taking the wrong approach entirely, but I could use some direction.