Frage

Ich habe Testanwendung zum Testen erstellt, StringBuilder -Kopierdaten in eine andere Instanz und erweitert IT -Puffer, wenn seine Länge mehr als die aktuelle Kapazität ist, und verifizieren Sie in iildasm.exe, aber es scheint identisch.

So überprüfen Sie StringBuilder, das seine Daten in eine neue Instanz kopiert und den Puffer nach der angegebenen Grenze erweitert?

War es hilfreich?

Lösung

Wenn Sie untersuchen möchten, wie StringBuilder implementiert wird, steuern Sie einfach den Reflektor und schauen Sie sich ihn an. Die Implementierung für StringBuilder.Append(string) ist wie folgt

public StringBuilder Append(string value)
{
   if (value != null)
   {
      string stringValue = this.m_StringValue;
      IntPtr currentThread = Thread.InternalGetCurrentThread();
      if (this.m_currentThread != currentThread)
      {
         stringValue = string.GetStringForStringBuilder(stringValue, stringValue.Capacity);
      }
      int length = stringValue.Length;
      int requiredLength = length + value.Length;
      if (this.NeedsAllocation(stringValue, requiredLength))
      {
         string newString = this.GetNewString(stringValue, requiredLength);
         newString.AppendInPlace(value, length);
         this.ReplaceString(currentThread, newString);
      }
      else
      {
         stringValue.AppendInPlace(value, length);
         this.ReplaceString(currentThread, stringValue);
      }
   }
   return this;
}

Schauen Sie sich den Abschnitt mit NeedsAllocation, GetNewString Und so weiter, um zu finden, wonach Sie suchen.

Andere Tipps

Die Kapazität repräsentiert den zusammenhängenden Speicher, der dem StringBuilder zugewiesen wurde. Die Kapazität kann> = Länge der Zeichenfolge sein. Wenn mehr Daten an den StringBuilder als an die Kapazität angehängt werden, erhöht StringBuilder die Kapazität automatisch. Da die Kapazität überschritten ist (dh an zusammenhängender Speicher wird gefüllt und kein Pufferraum mehr verfügbar), wird ein größerer Pufferbereich zugewiesen und die Daten werden vom ursprünglichen Speicher in diesen neuen Bereich kopiert.

Es kopiert keine Daten in eine neue "Instanz", sondern an einen neuen "Speicherort". Die Instanz bleibt gleich, weist aber auf den neuen Speicherort hin.

FYI bearbeiten: Standardkapazität von StringBuilder, wenn nicht während der Erstellung angegeben ist

Wenn Sie die Speicherorte für StringBuilder sehen möchten, können Sie Ihre Anwendungen debuggen und den Speicher mit Debug> Windows> Speicher überprüfen. Sie können tatsächlich die Adresse jedes einzelnen Byte sehen, das in Ihrem StringBuilder gespeichert ist, wenn Sie STMT -Ausführungen anhängen.

Wenn Sie die Standorte programmatisch erhalten müssen dieser Link könnte helfen.

Nicht, dass wir wirklich testen, dass StringBuilder funktioniert, weil dies der Fall ist, aber zu Ihrem eigenen Genuss können Sie immer einen Unit -Test schreiben.

StringBuilder sb = new StringBuilder(10);
Console.WriteLine("Capacity = " + sb.Capacity + " Length = " + sb.Length 
      + " MaxCapacity = " + sb.MaxCapacity);
sb.Append("1234567890");
sb.Append("1234567890");
sb.Append("1234567890");
Console.WriteLine("Capacity = " + sb.Capacity + " Length = " + sb.Length 
      + " MaxCapacity = " + sb.MaxCapacity);
Assert.AreEqual("123456789012345678901234567890"
      , sb.ToString()); // NUnit assert.

Es ist nicht überraschend, dass es vergeht und die folgende Ausgabe angegeben wird.

    Capacity = 10 Length = 0 MaxCapacity = 2147483647
    Capacity = 40 Length = 30 MaxCapacity = 2147483647

Die Art und Weise, wie der StringBuilder bei Bedarf seinen Puffer erhöht, wird durch den internen Code des StringBuilders erledigt. Es wird im IL -Code Ihrer Anwendung nicht angezeigt. Der Compiler kann nicht wissen, wie groß der StringBuilder in einer bestimmten Methode enthalten wird, da dies von Zeit zu Zeit variieren kann.

Wenn jedoch der StringBuilder tut Erhöhen Sie seinen Puffer, es wird nicht zu einer neuen StringBuilder -Instanz führen. Es kann dazu führen, dass es die interne Darstellung der Zeichenfolge kopiert, die sie an einer neuen Instanz hält (ich weiß nicht genug über das Innenleben der Klasse, um genau zu sagen, was passiert).

Sie können Reflektor verwenden, um so ziemlich genau zu sehen, wie StringBuilder funktioniert.

Siehe Methode

StringBuilder Append(string value)

Für .NET 3.5 Logic lautet: Wenn die Pufferlänge für die neue Zeichenfolge nicht ausreicht, erstellen Sie einen neuen Puffer mit Länge max (oldSize * 2, fordersze).

Mit anderen Worten, Stringbuffer versucht den Puffer zu verdoppeln, und wenn das nicht ausreicht, dann macht die Puffergröße gerade genug, um die neue Zeichenfolge anzupassen.

Der Hinweis auf den alten Puffer wird entfernt und der alte Puffer wird mit der nächsten Müllsammlung zurückgefordert.

 class Program
    {
        static void Main()
        {
            StringBuilder sb = new StringBuilder();
            Console.WriteLine(sb.Capacity); //16

            for (int i = 0; i < 50; i++) 
                sb.Append(i + ",");

            Console.WriteLine(sb.Capacity); //256

            sb = new StringBuilder();
            Console.WriteLine(sb.Capacity); //16
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top