this is what I'm trying to achieve:
config.Name("Foo")
.Elements(() => {
Element.Name("element1").Height(23);
Element.Name("element2").Height(31);
})
.Foo(23);
or like this:
.Elements(e => {
e.Name("element1").Height(23);
e.Name("element2").Height(31);
})
.Foo(3232);
this is what I have for the moment:
public class Config
{
private string name;
private int foo;
private IList<Element> elements = new List<Element>();
public Config Name(string name)
{
this.name = name;
return this;
}
public Config Foo(int x)
{
this.foo = x;
}
... //add method for adding elements
class Element
{
public string Name { get; set; }
public int Height { get; set; }
}
}
anybody knows how to do this ?
Any reason you don't want to use object and collection initializers?
public class Config
{
public string Name { get; set; }
public int Foo { get; set; }
public IList<Element> Elements { get; private set; }
public Config()
{
Elements = new List<Element>();
}
}
// I'm assuming an element *always* needs a name and a height
class Element
{
public string Name { get; private set; }
public int Height { get; private set; }
public Element(string name, int height)
{
this.Name = name;
this.Height = height;
}
}
Then:
var config = new Config
{
Name = "Foo",
Elements = {
new Element("element1", 23),
new Element("element2", 31)
},
Foo = 23
};
If you don't want to expose the list of elements directly, you could always turn that into a builder, and copy it into a more private data structure on Build
:
var config = new Config.Builder
{
Name = "Foo",
Elements = {
new Element("element1", 23),
new Element("element2", 31)
},
Foo = 23
}.Build();
This has the additional advantage that you can make Config
itself immutable.
If you always need Name
to be present, just take that as a constructor parameter instead.
While there are times where it's good to have a fluent interface with mutating (or copy-and-change) method calls, in this case I think collection/object initializers are more idiomatic C#.
Note that if you're using C# 4 and you want to make your Element
constructor calls, you can always use named arguments:
new Element(name: "element2", height: 31)