web-dev-qa-db-ja.com

StringBuilderを使用するためのベストプラクティス

さまざまなコマンドごとに多くの方法を使用するカメラ制御プログラムを書いています。

1つの例は次のとおりです。

public void CameraPan(int Id, string Direction, int Speed)
{
    StringBuilder sb = new StringBuilder();
    sb.Append(_cameraRamp); //command to camera - start moving
    sb.Append(_camID);
    sb.Append(Convert.ToString(Id));
    sb.Append(_pan); //command to camera - this is a pan
    sb.Append(Direction);
    sb.Append(_panSpeed); //command to camera - speed to move at
    sb.Append(Convert.ToString(Speed));
    _sendCommand = sb.ToString();
    SendToCamera(_sendCommand);
}

私の質問-各メソッドに対して新しいStringBuilderをインスタンス化するか、クラスに対して1つのStringBuilderを構築してそれを全体的に使用することがベストプラクティスですか?

全体で使用すると、コミットされるリソースが少なくなるようです。一方、メソッドが使用されなくなったとき、GCは各インスタンスを単に破棄しないのではないですか?

5
Norm Schaeffer

メソッドごとにStringBuilderをインスタンス化します。

理由は次のとおりです。

  1. Encapsulation。各メソッドには、それが制御する独自のStringBuilderオブジェクトがあるため、StringBuilder状態を使用して他のことを心配する必要はありません。

  2. StringBuildersはインスタンス化するための安価なオブジェクトであり、文字列を連結するよりもはるかに安価です。

グローバルStringBuilderオブジェクトを共有すると、特にスレッドセーフを維持しようとしている場合は、あらゆる種類の微妙で潜行性のある、バグのトラブルシューティングが困難な繁殖地が生まれます。

13
Robert Harvey

新しいStringBuilderが必要な場合は、必ず新しいStringBuilderを使用してください。

他の何かはおそらくカプセル化を壊しており、オブジェクトを共有することの望ましくない副作用にあなたを開いたままにします。

また、単純なAppend()の代わりにAppendFormat()を使用することをお勧めします。
ここではかなり複雑な(そして、おそらくフォーマットに依存する)文字列を作成しているので、フォーマットを明示的にロックダウンすると、後で頭痛の種を省くことができます。

sb.AppendFormat("{0}{1}{2:0}{3}{4}{5:0}" 
   , _cameraRamp  /* start moving */ 
   , _camID
   , Id 
   , _pan         /* this is a pan */ 
   , Direction  
   , _panSpeed    /* speed to move at */ 
   , Speed 
   ); 

_sendCommand = sb.ToString();

SendToCamera(_sendCommand);
6
Phill W.