我有一个序列化任务,其中我的对象模型的不同部分知道如何发出自己的字符串段,但是我希望可以使用.Append
针对常见的StringBuilder
对象发出它们。根据理论,我们不应该把我们的私人对象传递给别人滥用,下面是一个包装StringBuilder
的类,使它成为“仅用于追加”用于我的场景。绕过一个“AppendOnlyStringBuilder”
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;
}
}
如果我的模型的不同块的内部代码,现在所有类似于此:
// Chunk1 class
public override string ToString() {
StringBuilder sb = new StringBuilder();
sb
.Append(_prop1.Value)
.Append(_prop2.Value)
.Append(_prop3.Value);
return sb.ToString();
}
而且这些ToString
方法是从主程序的序列化方法被称为像这样:
// MainObject class
Chunk1 _chunk1;
Chunk2 _chunk2;
Chunk3 _chunk3;
public override string ToString() {
StringBuilder sb = new StringBuilder();
sb
.Append(_chunk1.ToString()) // ToString may be unnecessary here
.Append(_chunk2.ToString())
.Append(_chunk3.ToString());
return sb.ToString();
}
如何优雅地切换到单个AppendOnlyStringBuilder
以便在所有这些块类中使用,而不是在内部创建新的StringBuilder
和ToString
?
我想它要使用这样的事:
// 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();
}
扩展方法是一种自然的方式来得到这个语法,但我运行到由于扩展方法的问题需要被静态,因此无法访问Chunk类的私有部分。我想在大块类中保留相同的ToString
,这样他们仍然可以按照正常的“序列化我”的方式进行操作,但是我也希望它们能够选择附加到我的共同AppendOnlyStringBuilder
。
我想我能做到这一点:
_chunk1.AppendTo(aosb);
_chunk2.AppendTo(aosb);
_chunk3.AppendTo(aosb);
但一些事困扰我 - 我倒是喜欢用与AppendOnlyStringBuilder
对象开始在以前我的例子能说一口流利的接口。
各种'Chunk'类将只有一个'AppendOnlyStringBuilder'访问。他们怎么能对主对象实例化并保持私有的底层对象做任何事情? – ErikE
我会设置一个系统,让对象序列化到TextWriter(但如果您愿意,可以继续使用StringBuilder)。然后ToString覆盖只是创建一个新的TW(或SB),调用另一个方法并返回结果。 serialize方法可以是抽象的,并且ToString重写只能在基类中定义一次。这失去了方法链,但我不认为这是一个很大的损失。您可能可以使用访问者模式保留它。我不确定这项工作是否值得。 – phoog
@phoog只要我们不结束重复字符串连接的问题,'TextWriter'也可以。你能给出一些示例代码来概述你的想法吗? – ErikE