イディオム:StringBuilder

静的メソッド ToString では、リターン値を得るために、変数 buf が作業領域 StringBuilder を保持します。StringBuilder を使うと(可変型の)文字列を編集(追加/削除/置換/挿入)したいときに便利です。すると、次のような構造が見えてきます。

   StringBuilder buf = new StringBuilder();
... buf.Append("...") ... // 文字列を末尾に追加する
return buf.ToString();

メソッド StringBuilder.Append を利用して、作業領域 buf の末尾に文字列を追加しながら、最後に、メソッド StringBuilder.ToString を利用して、リターン値となる文字列を得ているのが分かります。
《参照》クラス StringBuilder:詳細は C# idioms を参照してください。


Previous〈2/3〉Next

ソースコード:Dict.ToString()

(メソッド dict.__str__ に相当する)メソッド ToString の定義を含む、ソースコードの断片を次に示します。

# IronPython-1.1.2/Src/IronPython/Runtime/Dict.cs
namespace IronPython.Runtime {

[PythonType("dict")]
public class Dict : ... IDictionary ... {
...
#region Object overrides
[PythonName("__str__")]
public override string ToString() {
return DictOps.ToString(this);
}

まず、目に付くのは、名前空間に関する次の記述です。

namespace IronPython.Runtime {

これを見ると、ソースファイル Dict.cs を含む、フォルダーの階層 IronPython\Runtime に相当するのが分かります。次に、クラス Dict のヘッダーを見ると、

    [PythonType("dict")]

ここで組み込み型 dict を定義しているのが分かります。さらに、メソッド ToString のヘッダーを見ると、次のように、

    #region Object overrides
[PythonName("__str__")]

これが dict.__str__ に相当するのが分かります。コメントを見ると、この後に続くメソッド群が、クラス Object にあるものを再定義 overrides したものだと分かります。

メソッド:ToString

メソッド ToString では、次のように、

    return DictOps.ToString(this);

実引数に、this を指定しています。これは、内部クラス DictOps ですべての操作を実現しているので、それに自身 this の処理を委ねるためです。このとき(Dict のインスタンス)this は、インターフェース IDictionary の規定に従うものとします。
《参照》インターフェイス IDictionary:詳細は C# idioms を参照してください。

ソースコード:DictOps.ToString()

内部クラス DictOps では、クラス Dict で規定するメソッドに対して、実質的な処理群(Ops)を実現します。これらのメソッドは static 宣言してあり、メソッド呼び出しの対象となるインスタンス自身(実引数 this)が、仮引数 self になります。つまり、static 宣言することで、一連のメソッドを「関数」として再定義するのです。

    internal static class DictOps {
static object nullObject = new object();

public static string ToString(IDictionary self) {
StringBuilder buf = new StringBuilder();
buf.Append("{");
bool first = true;
foreach (KeyValuePair kv in self) {
if (first) first = false;
else buf.Append(", ");

if (kv.Key == nullObject)
buf.Append("None");
else
buf.Append(Ops.StringRepr(kv.Key));
buf.Append(": ");
buf.Append(Ops.StringRepr(kv.Value));
}
buf.Append("}");
return buf.ToString();
}