I've customized a C# class for chaining calls to add my styles, but when I first create an instance of the style class and then use chaining calls, it only displays the first added style in the end.
Here is the code:
MyStyleBuilder:
namespace TestStyleBuilder
{
public struct MyStyleBuilder
{
private string stringBuffer;
public MyStyleBuilder AddLineColor(string value) => this.AddStyle("color", value);
public MyStyleBuilder AddLineDash(string value) => this.AddStyle("dash", value);
public MyStyleBuilder AddStyle(string prop, string value)
{
var style = $"{prop}:{value};";
stringBuffer += style;
return this;
}
public override string ToString()
{
return stringBuffer != null ? stringBuffer.Trim() : string.Empty;
}
}
}
Test:
using TestStyleBuilder;
// Output:
// color:color;dash:dash;
MyStyleBuilder builder1 = new MyStyleBuilder().AddLineColor("color").AddLineDash("dash");
Console.WriteLine(builder1.ToString());
// Output:
// color:color;
MyStyleBuilder builder2 = new MyStyleBuilder();
builder2.AddLineColor("color").AddLineDash("dash");
Console.WriteLine(builder2.ToString());
After debugging and tracing, I found that all the styles were added in the MyStyleBuilder, but when returning to the test class, only one style was added.
My guess is that in the second example, the returned this is not equivalent to builder2, which is causing this behavior.
However, I'm not sure how to modify it to achieve the desired effect of continuous style addition in the second approach.
When you return this
from a struct method, a copy of this
is returned, because structs have value semantics.
builder2.AddLineColor("color")
is modifying builder2.stringBuffer
, but AddLineDash("dash")
is modifying the stringBuffer
of the copy returned by builder2.AddLineColor("color")
. That's why when you inspect builder2.stringBuffer
, only the color is applied. The copy returned by AddLineDash("dash")
has both styles applied, but you discarded that by not assigning to anything.
You can assign builder2
the result of the chain:
builder2 = builder2.AddLineColor("color").AddLineDash("dash");
Or just change MyStyleBuilder
to a class
, which will give it reference semantics.
public class MyStyleBuilder
See also What's the difference between struct and class in .NET?