c# - Pass around an "AppendOnlyStringBuilder" -


i have serialization task different parts , pieces of object model know how emit own string segments, i'd option emit them using .append against common stringbuilder object. on theory should not pass around our private objects others use indiscriminately, here's class wraps stringbuilder make "append-only" use in scenario.

public sealed class appendonlystringbuilder {    private readonly stringbuilder _stringbuilder;     public appendonlystringbuilder(stringbuilder stringbuilder)    {       _stringbuilder = stringbuilder;    }     public appendonlystringbuilder append<t>(t value)    {       _stringbuilder.append(value);       return this;    } } 

if code inside of different chunks of model right similar this:

// chunk1 class public override string tostring() {    stringbuilder sb = new stringbuilder();    sb       .append(_prop1.value)       .append(_prop2.value)       .append(_prop3.value);    return sb.tostring(); } 

and these tostring methods called main routine's serialization method so:

// mainobject class chunk1 _chunk1; chunk2 _chunk2; chunk3 _chunk3;  public override string tostring() {    stringbuilder sb = new stringbuilder();    sb       .append(_chunk1.tostring()) // tostring may unnecessary here       .append(_chunk2.tostring())       .append(_chunk3.tostring());    return sb.tostring(); } 

how can elegantly switch passing around single appendonlystringbuilder use in these chunk classes instead of each 1 internally creating new stringbuilder , doing tostring?

i'd used this:

// mainobject class public override string tostring() {    stringbuilder sb = new stringbuilder();    appendonlystringbuilder aosb = new appendonlystringbuilder(sb);    aosb       .append(_chunk1)       .append(_chunk2)       .append(_chunk3);    return sb.tostring(); } 

an extension method natural way syntax, i'm running problems due extension method needing static , not able access private parts of chunk classes. i'd keep same tostring in chunk classes can still normal "serialize me" thing, i'd them able optionally append common appendonlystringbuilder.

i guess this:

_chunk1.appendto(aosb); _chunk2.appendto(aosb); _chunk3.appendto(aosb); 

but bugs me--i'd use fluent interface begins appendonlystringbuilder object in example previously.

ok, here goes:

using system.io;  abstract class baseclass {     protected abstract void writetotextwriter(textwriter textwriter);      public void serializeto(textwriter textwriter)     {         writetotextwriter(textwriter);     }      public sealed override string tostring()     {         var writer = new stringwriter();         serializeto(writer);         return writer.tostring();     } }  abstract class chunkbase : baseclass {     private readonly string _index;      protected chunkbase(string index)     {         _index = index;     }      protected sealed override void writetotextwriter(textwriter textwriter)     {         textwriter.write("chunk");         textwriter.write(_index);     } }  class chunk1 : chunkbase { public chunk1() : base("1") { } } class chunk2 : chunkbase { public chunk2() : base("2") { } } class chunk3 : chunkbase { public chunk3() : base("3") { } }  class classwithchunks : baseclass {     private readonly chunk1 _chunk1 = new chunk1();     private readonly chunk2 _chunk2 = new chunk2();     private readonly chunk3 _chunk3 = new chunk3();      protected override void writetotextwriter(textwriter textwriter)     {         _chunk1.serializeto(textwriter);         _chunk2.serializeto(textwriter);         _chunk3.serializeto(textwriter);     } } 

now, if want chaining, this:

class chainable {     private readonly textwriter _textwriter;      public chainable(textwriter textwriter)     {         _textwriter = textwriter;     }      public chainable write(baseclass obj)     {         obj.serializeto(_textwriter);         return this;     } } 

then, writetotextwriter be, example, this:

public override void writetotextwriter(textwriter textwriter) {     new chainable(textwriter)         .write(_chunk1)         .write(_chunk2)         .write(_chunk3); } 

i'm not sure it's worth it: code cleaner, harder (including future self) decipher, because of additional layer of complexity.

edit: making abstract method protected seems add little here, in production code, layer helpful. you'll want add switches, too, handle formatting , like.


Comments