Foo
ToString メソッドをオーバーライドして内部状態を出力するクラス (例: ) があります。このクラスには、Foo
子要素のコレクションがあります。子供は子供などを産むこともできます。
子要素を自動的にインデントするような方法で ToString() に実装するソリューションを探しています。
Parent Foo
Child1 Foo
Child1.1 Foo
Child2 Foo
Child2.1 Foo
Child2.2 Foo
Foo
ToString メソッドをオーバーライドして内部状態を出力するクラス (例: ) があります。このクラスには、Foo
子要素のコレクションがあります。子供は子供などを産むこともできます。
子要素を自動的にインデントするような方法で ToString() に実装するソリューションを探しています。
Parent Foo
Child1 Foo
Child1.1 Foo
Child2 Foo
Child2.1 Foo
Child2.2 Foo
ToString()
解決策は、出力するサブツリーのルートで呼び出される「エントリ ポイント」としてのみ使用することです。そのメソッドは、現在のインデント レベルを引数として受け取るToString()
プライベート メソッドを呼び出すことができます。ToIndentedString(int)
そのメソッドは、指定されたインデントにある現在のノードの文字列表現に加えて、インデント + 1 にあるすべての子ノードの文字列表現を返します。
public string ToString()
{
return ToIndentedString(0);
}
private string ToIndentedString(int indentation)
{
StringBuilder result = new StringBuilder();
result.Append(' ', indentation);
result.Append(Environment.NewLine);
foreach (Foo child in children) {
result.Append(child.ToIndentedString(indentation + 1));
}
return result.ToString();
}
次のように使用IFormattable
することもできます。Foo
public class Foo : IFormattable
{
public string Text { get; set; }
public IList<Foo> InnerList { get; set; }
public string ToString(string format, IFormatProvider formatProvider)
{
if (String.IsNullOrEmpty(format)) format = "0";
if (formatProvider == null) formatProvider = CultureInfo.CurrentCulture;
int indent = 0;
Int32.TryParse(format, out indent);
string indentString = "";
while(indent > indentString.Length)
{
indentString += " ";
}
var toString = String.Format("{0}{1}", indentString, Text);
foreach (Foo foo in InnerList ?? new List<Foo>())
{
toString += String.Format("\n{0}", foo.ToString((indent + 1).ToString(), formatProvider));
}
return toString;
}
public override string ToString()
{
return ToString("0", CultureInfo.CurrentCulture);
}
}
この場合、次のこともできます。
String.Format("{0:5}", foo); // Start with 5 indents
または
foo.ToString("7", CultureInfo.CurrentCulture); // Also start with indents (7 in this case)
string spacing = " ";
string newLineSpacing = string.Format("{0}{1}", Environment.NewLine, spacing);
StringBuilder sb = new StringBuilder("mydata");
foreach (Foo child in children)
{
sb.Append(Environment.NewLine);
sb.Append(spacing);
sb.Append(child.ToString().Replace(Environment.NewLine, newLineSpacing));
}
現在、開発マシンを再構築しているため、テストされていません。