System.Text.StringBuilder-klasse

Notitie

In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.

De StringBuilder klasse vertegenwoordigt een tekenreeksachtig object waarvan de waarde een veranderlijke reeks tekens is.

StringBuilder versus tekenreekstype

Hoewel StringBuilder beide String tekensreeksen vertegenwoordigen, worden ze anders geïmplementeerd. String is een onveranderbaar type. Dat wil gezegd, elke bewerking die een String object lijkt te wijzigen, maakt daadwerkelijk een nieuwe tekenreeks.

De aanroep van de methode in het volgende C#-voorbeeld lijkt bijvoorbeeld de waarde van een tekenreeksvariabele met de String.Concat naam valuete wijzigen. In feite retourneert de Concat methode een value object met een andere waarde en een ander adres dan het value object dat is doorgegeven aan de methode. Houd er rekening mee dat het voorbeeld moet worden gecompileerd met behulp van de /unsafe compileroptie.

using System;

public class Example7
{
    public unsafe static void Main()
    {
        string value = "This is the first sentence" + ".";
        fixed (char* start = value)
        {
            value = String.Concat(value, "This is the second sentence. ");
            fixed (char* current = value)
            {
                Console.WriteLine(start == current);
            }
        }
    }
}
// The example displays the following output:
//      False
    let mutable value = "This is the first sentence" + "."
    use start = fixed value
    value <- System.String.Concat(value, "This is the second sentence. ")
    use current = fixed value
    printfn $"{start = current}"
// The example displays the following output:
//      False

Voor routines die uitgebreide tekenreeksbewerkingen uitvoeren (zoals apps die een tekenreeks meerdere keren in een lus wijzigen), kan het herhaaldelijk wijzigen van een tekenreeks een aanzienlijke prestatiestraf uitoefenen. Het alternatief is om te gebruiken StringBuilder, een veranderlijke tekenreeksklasse. Mutabiliteit betekent dat wanneer een instantie van de klasse is gemaakt, deze kan worden gewijzigd door tekens toe te voegen, te verwijderen, te vervangen of in te voegen.

Belangrijk

Hoewel de StringBuilder klasse over het algemeen betere prestaties biedt dan de String klasse, moet u niet automatisch String vervangen door StringBuilder wanneer u tekenreeksen wilt bewerken. Prestaties zijn afhankelijk van de grootte van de tekenreeks, de hoeveelheid geheugen die moet worden toegewezen voor de nieuwe tekenreeks, het systeem waarop uw code wordt uitgevoerd en het type bewerking. U moet bereid zijn om uw code te testen om te bepalen of StringBuilder daadwerkelijk een aanzienlijke verbetering in prestaties biedt.

Overweeg het gebruik van de String klasse onder deze voorwaarden:

  • Wanneer het aantal wijzigingen dat uw code aanbrengt in een tekenreeks klein is. In deze gevallen kan StringBuilder te verwaarlozen of geen prestatieverbetering bieden ten opzichte van String.
  • Wanneer u een vast aantal samenvoegbewerkingen uitvoert, met name met letterlijke tekenreeksen. In dit geval kan de compiler de samenvoegingsbewerkingen combineren tot één bewerking.
  • Wanneer u uitgebreide zoekbewerkingen moet uitvoeren terwijl u uw tekenreeks bouwt. De StringBuilder klasse mist zoekmethoden zoals IndexOf of StartsWith. U moet het StringBuilder object converteren naar een String voor deze bewerkingen. Dit kan het voordeel van het gebruik van StringBuilderde prestaties vernieten. Zie de tekst zoeken in een stringBuilder-objectsectie voor meer informatie.

Overweeg het gebruik van de StringBuilder klasse onder deze voorwaarden:

  • Wanneer u verwacht dat uw code tijdens het ontwerp een onbekend aantal wijzigingen aanbrengt in een tekenreeks (bijvoorbeeld wanneer u een lus gebruikt om een willekeurig aantal tekenreeksen samen te voegen die gebruikersinvoer bevatten).
  • Wanneer u verwacht dat uw code een aanzienlijk aantal wijzigingen aanbrengt in een tekenreeks.

Hoe StringBuilder werkt

De StringBuilder.Length eigenschap geeft het aantal tekens aan dat het StringBuilder object momenteel bevat. Als u tekens aan het StringBuilder object toevoegt, wordt de lengte ervan verhoogd totdat deze gelijk is aan de grootte van de StringBuilder.Capacity eigenschap, waarmee het aantal tekens wordt gedefinieerd dat het object kan bevatten. Als het aantal toegevoegde tekens ervoor zorgt dat de lengte van het StringBuilder object de huidige capaciteit overschrijdt, wordt er een nieuw geheugen toegewezen, wordt de waarde van de Capacity eigenschap verdubbeld, worden nieuwe tekens aan het object toegevoegd en StringBuilder wordt de Length eigenschap ervan aangepast. Extra geheugen voor het StringBuilder object wordt dynamisch toegewezen totdat de waarde wordt bereikt die is gedefinieerd door de StringBuilder.MaxCapacity eigenschap. Wanneer de maximale capaciteit is bereikt, kan er geen geheugen meer worden toegewezen voor het StringBuilder object en wordt geprobeerd tekens toe te voegen of uit te breiden buiten de maximale capaciteit, wordt er een ArgumentOutOfRangeException of een OutOfMemoryException uitzondering gegenereerd.

In het volgende voorbeeld ziet u hoe een StringBuilder object nieuw geheugen toewijst en de capaciteit dynamisch verhoogt naarmate de tekenreeks die aan het object is toegewezen, wordt uitgebreid. Met de code wordt een StringBuilder object gemaakt door de standaardconstructor (parameterloos) aan te roepen. De standaardcapaciteit van dit object is 16 tekens en de maximale capaciteit is meer dan 2 miljard tekens. Als u de tekenreeks 'Dit is een zin' toevoegt, resulteert dit in een nieuwe geheugentoewijzing omdat de tekenreekslengte (19 tekens) de standaardcapaciteit van het StringBuilder object overschrijdt. De capaciteit van het object verdubbelt tot 32 tekens, de nieuwe tekenreeks wordt toegevoegd en de lengte van het object is nu gelijk aan 19 tekens. De code voegt vervolgens de tekenreeks 'Dit is een extra zin' toe aan de waarde van het StringBuilder object 11 keer. Wanneer de toevoegbewerking ervoor zorgt dat de lengte van het StringBuilder object de capaciteit overschrijdt, wordt de bestaande capaciteit verdubbeld en slaagt de Append bewerking.

using System;
using System.Reflection;
using System.Text;

public class Example4
{
    public static void Main()
    {
        StringBuilder sb = new StringBuilder();
        ShowSBInfo(sb);
        sb.Append("This is a sentence.");
        ShowSBInfo(sb);
        for (int ctr = 0; ctr <= 10; ctr++)
        {
            sb.Append("This is an additional sentence.");
            ShowSBInfo(sb);
        }
    }

    private static void ShowSBInfo(StringBuilder sb)
    {
        foreach (var prop in sb.GetType().GetProperties())
        {
            if (prop.GetIndexParameters().Length == 0)
                Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
        }
        Console.WriteLine();
    }
}
// The example displays the following output:
//    Capacity: 16    MaxCapacity: 2,147,483,647    Length: 0
//    Capacity: 32    MaxCapacity: 2,147,483,647    Length: 19
//    Capacity: 64    MaxCapacity: 2,147,483,647    Length: 50
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 81
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 112
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 143
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 174
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 205
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 236
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 267
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 298
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 329
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 360
open System.Text

let showSBInfo (sb: StringBuilder) =
    for prop in sb.GetType().GetProperties() do
        if prop.GetIndexParameters().Length = 0 then
            printf $"{prop.Name}: {prop.GetValue sb:N0}    "

    printfn ""

let sb = StringBuilder()
showSBInfo sb
sb.Append "This is a sentence." |> ignore
showSBInfo sb

for i = 0 to 10 do
    sb.Append "This is an additional sentence." |> ignore
    showSBInfo sb

// The example displays the following output:
//    Capacity: 16    MaxCapacity: 2,147,483,647    Length: 0
//    Capacity: 32    MaxCapacity: 2,147,483,647    Length: 19
//    Capacity: 64    MaxCapacity: 2,147,483,647    Length: 50
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 81
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 112
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 143
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 174
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 205
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 236
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 267
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 298
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 329
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 360
Imports System.Reflection
Imports System.Text

Module Example5
    Public Sub Main()
        Dim sb As New StringBuilder()
        ShowSBInfo(sb)
        sb.Append("This is a sentence.")
        ShowSBInfo(sb)
        For ctr As Integer = 0 To 10
            sb.Append("This is an additional sentence.")
            ShowSBInfo(sb)
        Next
    End Sub

    Public Sub ShowSBInfo(sb As StringBuilder)
        For Each prop In sb.GetType().GetProperties
            If prop.GetIndexParameters().Length = 0 Then
                Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb))
            End If
        Next
        Console.WriteLine()
    End Sub
End Module
' The example displays the following output:
'    Capacity: 16    MaxCapacity: 2,147,483,647    Length: 0
'    Capacity: 32    MaxCapacity: 2,147,483,647    Length: 19
'    Capacity: 64    MaxCapacity: 2,147,483,647    Length: 50
'    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 81
'    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 112
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 143
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 174
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 205
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 236
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 267
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 298
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 329
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 360

Geheugentoewijzing

De standaardcapaciteit van een StringBuilder object is 16 tekens en de standaard maximale capaciteit is Int32.MaxValue. Deze standaardwaarden worden gebruikt als u de StringBuilder() en StringBuilder(String) constructors aanroept.

U kunt de oorspronkelijke capaciteit van een StringBuilder object expliciet definiëren op de volgende manieren:

  • Door een van de StringBuilder constructors aan te roepen die een capacity parameter bevatten wanneer u het object maakt.
  • Door expliciet een nieuwe waarde toe te wijzen aan de StringBuilder.Capacity eigenschap om een bestaand StringBuilder object uit te vouwen. (De eigenschap genereert een uitzondering als de nieuwe capaciteit kleiner is dan de bestaande capaciteit of groter is dan de maximale capaciteit van het StringBuilder object.)
  • Door de StringBuilder.EnsureCapacity methode aan te roepen met de nieuwe capaciteit. De nieuwe capaciteit mag niet groter zijn dan de maximale capaciteit van het StringBuilder object. In tegenstelling tot een toewijzing aan de Capacity eigenschap wordt EnsureCapacity er echter geen uitzondering gegenereerd als de gewenste nieuwe capaciteit kleiner is dan de bestaande capaciteit. In dit geval heeft de methode-aanroep geen effect.

Als de lengte van de tekenreeks die is toegewezen aan het StringBuilder object in de constructor-aanroep de standaardcapaciteit of de opgegeven capaciteit overschrijdt, wordt de Capacity eigenschap ingesteld op de lengte van de tekenreeks die is opgegeven met de value parameter.

U kunt expliciet de maximale capaciteit van een StringBuilder object definiëren door de StringBuilder(Int32, Int32) constructor aan te roepen. U kunt de maximale capaciteit niet wijzigen door een nieuwe waarde toe te wijzen aan de MaxCapacity eigenschap, omdat deze alleen-lezen is.

Zoals in de vorige sectie wordt weergegeven, wordt, wanneer de bestaande capaciteit onvoldoende is, extra geheugen toegewezen en verdubbelt de capaciteit van een StringBuilder object tot de waarde die door de MaxCapacity eigenschap is gedefinieerd.

Over het algemeen zijn de standaardcapaciteit en maximale capaciteit voldoende voor de meeste apps. U kunt overwegen deze waarden in te stellen onder de volgende voorwaarden:

  • Als de uiteindelijke grootte van het StringBuilder object waarschijnlijk uitermate groot wordt, meestal een omvang van meer dan enkele megabytes heeft. In dit geval kan er een prestatievoordeel zijn van het instellen van de oorspronkelijke Capacity eigenschap op een aanzienlijk hoge waarde om de noodzaak van te veel geheugenherplaatsingen te elimineren.
  • Als uw code wordt uitgevoerd op een systeem met beperkt geheugen. In dit geval kunt u overwegen om de MaxCapacity eigenschap in te stellen op minder dan Int32.MaxValue als uw code grote tekenreeksen verwerkt die ervoor kunnen zorgen dat deze wordt uitgevoerd in een omgeving met geheugenbeperkingen.

Een StringBuilder-object instantiëren

U instantieert een StringBuilder object door een van de zes overbelaste klasseconstructors aan te roepen, die worden vermeld in de volgende tabel. Drie van de constructors instantiëren een StringBuilder object waarvan de waarde een lege tekenreeks is, maar stellen zijn Capacity en MaxCapacity waarden anders in. De resterende drie constructors definiëren een StringBuilder object met een specifieke tekenreekswaarde en -capaciteit. Twee van de drie constructors gebruiken de standaard maximale capaciteit van Int32.MaxValue, terwijl u met de derde de maximale capaciteit kunt instellen.

Constructeur Stringwaarde Capaciteit Maximumcapaciteit
StringBuilder() String.Empty 16 Int32.MaxValue
StringBuilder(Int32) String.Empty Gedefinieerd door de capacity parameter Int32.MaxValue
StringBuilder(Int32, Int32) String.Empty Gedefinieerd door de capacity parameter Gedefinieerd door de maxCapacity parameter
StringBuilder(String) Gedefinieerd door de value parameter 16 of value. Length, afhankelijk van wat groter is Int32.MaxValue
StringBuilder(String, Int32) Gedefinieerd door de value parameter Gedefinieerd door de capacity parameter of value. Length, wat groter is. Int32.MaxValue
StringBuilder(String, Int32, Int32, Int32) Gedefinieerd door value. Substring(startIndex, length) Gedefinieerd door de capacity parameter of value. Length, wat groter is. Int32.MaxValue

In het volgende voorbeeld worden drie van deze constructor-overbelastingen gebruikt om StringBuilder objecten te instantiëren.

using System;
using System.Text;

public class Example8
{
    public static void Main()
    {
        string value = "An ordinary string";
        int index = value.IndexOf("An ") + 3;
        int capacity = 0xFFFF;

        // Instantiate a StringBuilder from a string.
        StringBuilder sb1 = new StringBuilder(value);
        ShowSBInfo(sb1);

        // Instantiate a StringBuilder from string and define a capacity.  
        StringBuilder sb2 = new StringBuilder(value, capacity);
        ShowSBInfo(sb2);

        // Instantiate a StringBuilder from substring and define a capacity.  
        StringBuilder sb3 = new StringBuilder(value, index,
                                              value.Length - index,
                                              capacity);
        ShowSBInfo(sb3);
    }

    public static void ShowSBInfo(StringBuilder sb)
    {
        Console.WriteLine($"\nValue: {sb.ToString()}");
        foreach (var prop in sb.GetType().GetProperties())
        {
            if (prop.GetIndexParameters().Length == 0)
                Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
        }
        Console.WriteLine();
    }
}
// The example displays the following output:
//    Value: An ordinary string
//    Capacity: 18    MaxCapacity: 2,147,483,647    Length: 18
//    
//    Value: An ordinary string
//    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 18
//    
//    Value: ordinary string
//    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 15
open System.Text

let showSBInfo (sb: StringBuilder) =
    for prop in sb.GetType().GetProperties() do
        if prop.GetIndexParameters().Length = 0 then
            printf $"{prop.Name}: {prop.GetValue sb:N0}    "

    printfn ""

let value = "An ordinary string"
let index = value.IndexOf "An " + 3
let capacity = 0xFFFF

// Instantiate a StringBuilder from a string.
let sb1 = StringBuilder value
showSBInfo sb1

// Instantiate a StringBuilder from string and define a capacity.
let sb2 = StringBuilder(value, capacity)
showSBInfo sb2

// Instantiate a StringBuilder from substring and define a capacity.
let sb3 = StringBuilder(value, index, value.Length - index, capacity)
showSBInfo sb3

// The example displays the following output:
//    Value: An ordinary string
//    Capacity: 18    MaxCapacity: 2,147,483,647    Length: 18
//
//    Value: An ordinary string
//    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 18
//
//    Value: ordinary string
//    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 15
Imports System.Text

Module Example8
    Public Sub Main()
        Dim value As String = "An ordinary string"
        Dim index As Integer = value.IndexOf("An ") + 3
        Dim capacity As Integer = &HFFFF

        ' Instantiate a StringBuilder from a string.
        Dim sb1 As New StringBuilder(value)
        ShowSBInfo(sb1)

        ' Instantiate a StringBuilder from string and define a capacity.  
        Dim sb2 As New StringBuilder(value, capacity)
        ShowSBInfo(sb2)

        ' Instantiate a StringBuilder from substring and define a capacity.  
        Dim sb3 As New StringBuilder(value, index,
                                   value.Length - index,
                                   capacity)
        ShowSBInfo(sb3)
    End Sub

    Public Sub ShowSBInfo(sb As StringBuilder)
        Console.WriteLine()
        Console.WriteLine("Value: {0}", sb.ToString())
        For Each prop In sb.GetType().GetProperties
            If prop.GetIndexParameters().Length = 0 Then
                Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb))
            End If
        Next
        Console.WriteLine()
    End Sub
End Module
' The example displays the following output:
'    Value: An ordinary string
'    Capacity: 18    MaxCapacity: 2,147,483,647    Length: 18
'    
'    Value: An ordinary string
'    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 18
'    
'    Value: ordinary string
'    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 15

Call StringBuilder-methoden

De meeste methoden waarmee de tekenreeks in een StringBuilder exemplaar wordt gewijzigd, retourneren een verwijzing naar datzelfde exemplaar. Hiermee kunt u methoden op twee manieren aanroepen StringBuilder :

  • U kunt afzonderlijke methode-aanroepen maken en de retourwaarde negeren, zoals in het volgende voorbeeld.

    using System;
    using System.Text;
    
    public class Example
    {
       public static void Main()
       {
          StringBuilder sb = new StringBuilder();
          sb.Append("This is the beginning of a sentence, ");
          sb.Replace("the beginning of ", "");
          sb.Insert(sb.ToString().IndexOf("a ") + 2, "complete ");
          sb.Replace(",", ".");
          Console.WriteLine(sb.ToString());
       }
    }
    // The example displays the following output:
    //        This is a complete sentence.
    
    open System.Text
    
    let sb = StringBuilder()
    sb.Append "This is the beginning of a sentence, " |> ignore
    sb.Replace("the beginning of ", "") |> ignore
    sb.Insert((string sb).IndexOf "a " + 2, "complete ") |> ignore
    sb.Replace(",", ".") |> ignore
    printfn $"{sb}"
    // The example displays the following output:
    //        This is a complete sentence.
    
    Imports System.Text
    
    Module Example2
        Public Sub Main()
            Dim sb As New StringBuilder()
            sb.Append("This is the beginning of a sentence, ")
            sb.Replace("the beginning of ", "")
            sb.Insert(sb.ToString().IndexOf("a ") + 2, "complete ")
            sb.Replace(",", ".")
            Console.WriteLine(sb.ToString())
        End Sub
    End Module
    ' The example displays the following output:
    '       This is a complete sentence.
    
  • U kunt een reeks methode-aanroepen uitvoeren in één instructie. Dit kan handig zijn als u één instructie wilt schrijven waarmee opeenvolgende bewerkingen worden gekoppeld. In het volgende voorbeeld worden drie methode-aanroepen uit het vorige voorbeeld samengevoegd tot één regel code.

    using System;
    using System.Text;
    
    public class Example2
    {
        public static void Main()
        {
            StringBuilder sb = new StringBuilder("This is the beginning of a sentence, ");
            sb.Replace("the beginning of ", "").Insert(sb.ToString().IndexOf("a ") + 2,
                                                       "complete ").Replace(",", ".");
            Console.WriteLine(sb.ToString());
        }
    }
    // The example displays the following output:
    //        This is a complete sentence.
    
    open System.Text
    
    let sb = StringBuilder "This is the beginning of a sentence, "
    
    sb
        .Replace("the beginning of ", "")
        .Insert((string sb).IndexOf "a " + 2, "complete ")
        .Replace(",", ".")
    |> ignore
    
    printfn $"{sb}"
    // The example displays the following output:
    //        This is a complete sentence.
    
    Imports System.Text
    
    Module Example3
        Public Sub Main()
            Dim sb As New StringBuilder("This is the beginning of a sentence, ")
            sb.Replace("the beginning of ", "").Insert(sb.ToString().IndexOf("a ") + 2,
                                                     "complete ").Replace(", ", ".")
            Console.WriteLine(sb.ToString())
        End Sub
    End Module
    ' The example displays the following output:
    '       This is a complete sentence.
    

StringBuilder-bewerkingen uitvoeren

U kunt de methoden van de StringBuilder klasse gebruiken om tekens in een StringBuilder object te herhalen, toe te voegen, te verwijderen of te wijzigen.

StringBuilder-tekens herhalen

U kunt de tekens in een StringBuilder object openen met behulp van de StringBuilder.Chars[] eigenschap. In C# Chars[] is een indexeerfunctie; in Visual Basic is dit de standaardeigenschap van de StringBuilder klasse. Hiermee kunt u afzonderlijke tekens instellen of ophalen met behulp van hun index, zonder expliciet naar de Chars[Int32] eigenschap te verwijzen. Tekens in een StringBuilder object beginnen bij index 0 (nul) en lopen door tot index Length - 1.

In het volgende voorbeeld ziet u de Chars[Int32] eigenschap. Het voegt tien willekeurige getallen toe aan een StringBuilder object en herhaalt vervolgens elk teken. Als de Unicode-categorie van het teken is UnicodeCategory.DecimalDigitNumber, wordt het getal met 1 verkleind (of wordt het getal gewijzigd in 9 als de waarde 0 is). In het voorbeeld wordt de inhoud van het StringBuilder object weergegeven voor en nadat de waarden van afzonderlijke tekens zijn gewijzigd.

using System;
using System.Globalization;
using System.Text;

public class Example3
{
    public static void Main()
    {
        Random rnd = new Random();
        StringBuilder sb = new StringBuilder();

        // Generate 10 random numbers and store them in a StringBuilder.
        for (int ctr = 0; ctr <= 9; ctr++)
            sb.Append(rnd.Next().ToString("N5"));

        Console.WriteLine("The original string:");
        Console.WriteLine(sb.ToString());

        // Decrease each number by one.
        for (int ctr = 0; ctr < sb.Length; ctr++)
        {
            if (Char.GetUnicodeCategory(sb[ctr]) == UnicodeCategory.DecimalDigitNumber)
            {
                int number = (int)Char.GetNumericValue(sb[ctr]);
                number--;
                if (number < 0) number = 9;

                sb[ctr] = number.ToString()[0];
            }
        }
        Console.WriteLine("\nThe new string:");
        Console.WriteLine(sb.ToString());
    }
}
// The example displays the following output:
//    The original string:
//    1,457,531,530.00000940,522,609.000001,668,113,564.000001,998,992,883.000001,792,660,834.00
//    000101,203,251.000002,051,183,075.000002,066,000,067.000001,643,701,043.000001,702,382,508
//    .00000
//    
//    The new string:
//    0,346,420,429.99999839,411,598.999990,557,002,453.999990,887,881,772.999990,681,559,723.99
//    999090,192,140.999991,940,072,964.999991,955,999,956.999990,532,690,932.999990,691,271,497
//    .99999
open System
open System.Globalization
open System.Text

let rnd = Random()
let sb = new StringBuilder()

// Generate 10 random numbers and store them in a StringBuilder.
for _ = 0 to 9 do
    rnd.Next().ToString "N5" |> sb.Append |> ignore

printfn "The original string:"
printfn $"{sb}"

// Decrease each number by one.
for i = 0 to sb.Length - 1 do
    if Char.GetUnicodeCategory(sb[i]) = UnicodeCategory.DecimalDigitNumber then
        let number = Char.GetNumericValue sb.[i] |> int
        let number = number - 1
        let number = if number < 0 then 9 else number
        sb.[i] <- number.ToString()[0]

printfn "\nThe new string:"
printfn $"{sb}"

// The example displays the following output:
//    The original string:
//    1,457,531,530.00000940,522,609.000001,668,113,564.000001,998,992,883.000001,792,660,834.00
//    000101,203,251.000002,051,183,075.000002,066,000,067.000001,643,701,043.000001,702,382,508
//    .00000
//
//    The new string:
//    0,346,420,429.99999839,411,598.999990,557,002,453.999990,887,881,772.999990,681,559,723.99
//    999090,192,140.999991,940,072,964.999991,955,999,956.999990,532,690,932.999990,691,271,497
//    .99999
Imports System.Globalization
Imports System.Text

Module Example4
    Public Sub Main()
        Dim rnd As New Random()
        Dim sb As New StringBuilder()

        ' Generate 10 random numbers and store them in a StringBuilder.
        For ctr As Integer = 0 To 9
            sb.Append(rnd.Next().ToString("N5"))
        Next
        Console.WriteLine("The original string:")
        Console.WriteLine(sb.ToString())
        Console.WriteLine()

        ' Decrease each number by one.
        For ctr As Integer = 0 To sb.Length - 1
            If Char.GetUnicodeCategory(sb(ctr)) = UnicodeCategory.DecimalDigitNumber Then
                Dim number As Integer = CType(Char.GetNumericValue(sb(ctr)), Integer)
                number -= 1
                If number < 0 Then number = 9

                sb(ctr) = number.ToString()(0)
            End If
        Next
        Console.WriteLine("The new string:")
        Console.WriteLine(sb.ToString())
    End Sub
End Module
' The example displays the following output:
'    The original string:
'    1,457,531,530.00000940,522,609.000001,668,113,564.000001,998,992,883.000001,792,660,834.00
'    000101,203,251.000002,051,183,075.000002,066,000,067.000001,643,701,043.000001,702,382,508
'    .00000
'    
'    The new string:
'    0,346,420,429.99999839,411,598.999990,557,002,453.999990,887,881,772.999990,681,559,723.99
'    999090,192,140.999991,940,072,964.999991,955,999,956.999990,532,690,932.999990,691,271,497
'    .99999

Het gebruik van indexering op basis van tekens met de Chars[Int32] eigenschap kan zeer traag zijn onder de volgende omstandigheden:

De prestaties zijn ernstig van invloed omdat elke tekentoegang de volledige gekoppelde lijst met segmenten doorloopt om de juiste buffer te vinden om in te indexeren.

Notitie

Zelfs voor een groot 'chunky' StringBuilder -object heeft het gebruik van de Chars[Int32] eigenschap voor op index gebaseerde toegang tot een of een klein aantal tekens een verwaarloosbare invloed op de prestaties. Dit is meestal een O(n) -bewerking. De aanzienlijke invloed op de prestaties treedt op wanneer de tekens in het StringBuilder object worden herhaald. Dit is een O(n^2) -bewerking.

Als u prestatieproblemen ondervindt bij het gebruik van indexering op basis van tekens met StringBuilder objecten, kunt u een van de volgende tijdelijke oplossingen gebruiken:

  • Converteer het StringBuilder exemplaar naar een String door de ToString methode aan te roepen en benader vervolgens de tekens in de tekenreeks.

  • Kopieer de inhoud van het bestaande StringBuilder object naar een nieuw, vooraf bepaald formaat StringBuilder object. De prestaties worden verbeterd omdat het nieuwe StringBuilder object niet chunky is. Voorbeeld:

    // sbOriginal is the existing StringBuilder object
    var sbNew = new StringBuilder(sbOriginal.ToString(), sbOriginal.Length);
    
    ' sbOriginal is the existing StringBuilder object
    Dim sbNew = New StringBuilder(sbOriginal.ToString(), sbOriginal.Length)
    
  • Stel de initiële capaciteit van het StringBuilder object in op een waarde die ongeveer gelijk is aan de maximale verwachte grootte door de StringBuilder(Int32) constructor aan te roepen. Houd er rekening mee dat hiermee het hele geheugenblok wordt toegewezen, zelfs als de StringBuilder maximale capaciteit zelden wordt bereikt.

Tekst toevoegen aan een StringBuilder-object

De StringBuilder klasse bevat de volgende methoden voor het uitbreiden van de inhoud van een StringBuilder object:

  • De Append methode voegt een tekenreeks, een subtekenreeks, een tekenmatrix, een gedeelte van een tekenmatrix, één teken dat meerdere keren wordt herhaald of de tekenreeksweergave van een primitief gegevenstype toe aan een StringBuilder object.

  • De AppendLine methode voegt een regeleindteken of een tekenreeks samen met een regeleindteken toe aan een StringBuilder object.

  • Met de AppendFormat methode wordt een tekenreeks met samengestelde opmaak toegevoegd aan een StringBuilder object. De tekenreeksweergaven van objecten die zijn opgenomen in de resultaattekenreeks kunnen de opmaakconventies van de huidige systeemcultuur of een opgegeven cultuur weerspiegelen.

  • Met Insert de methode wordt een tekenreeks, een subtekenreeks, meerdere herhalingen van een tekenreeks, een tekenmatrix, een gedeelte van een tekenmatrix of de tekenreeksweergave van een primitief gegevenstype ingevoegd op een opgegeven positie in het StringBuilder object. De positie wordt gedefinieerd door een op nul gebaseerde index.

In het volgende voorbeeld worden de Appendmethoden , AppendLineen AppendFormatInsertmethoden gebruikt om de tekst van een StringBuilder object uit te vouwen.

using System;
using System.Text;

public class Example6
{
    public static void Main()
    {
        // Create a StringBuilder object with no text.
        StringBuilder sb = new StringBuilder();
        // Append some text.
        sb.Append('*', 10).Append(" Adding Text to a StringBuilder Object ").Append('*', 10);
        sb.AppendLine("\n");
        sb.AppendLine("Some code points and their corresponding characters:");
        // Append some formatted text.
        for (int ctr = 50; ctr <= 60; ctr++)
        {
            sb.AppendFormat("{0,12:X4} {1,12}", ctr, Convert.ToChar(ctr));
            sb.AppendLine();
        }
        // Find the end of the introduction to the column.
        int pos = sb.ToString().IndexOf("characters:") + 11 +
                  Environment.NewLine.Length;
        // Insert a column header.
        sb.Insert(pos, String.Format("{2}{0,12:X4} {1,12}{2}", "Code Unit",
                                     "Character", "\n"));

        // Convert the StringBuilder to a string and display it.      
        Console.WriteLine(sb.ToString());
    }
}
// The example displays the following output:
//    ********** Adding Text to a StringBuilder Object **********
//    
//    Some code points and their corresponding characters:
//    
//       Code Unit    Character
//            0032            2
//            0033            3
//            0034            4
//            0035            5
//            0036            6
//            0037            7
//            0038            8
//            0039            9
//            003A            :
//            003B            ;
//            003C            <
open System
open System.Text

// Create a StringBuilder object with no text.
let sb = StringBuilder()
// Append some text.
sb
    .Append('*', 10)
    .Append(" Adding Text to a StringBuilder Object ")
    .Append('*', 10)
|> ignore

sb.AppendLine "\n" |> ignore
sb.AppendLine "Some code points and their corresponding characters:" |> ignore
// Append some formatted text.
for i = 50 to 60 do
    sb.AppendFormat("{0,12:X4} {1,12}", i, Convert.ToChar i) |> ignore
    sb.AppendLine() |> ignore

// Find the end of the introduction to the column.
let pos = (string sb).IndexOf("characters:") + 11 + Environment.NewLine.Length
// Insert a column header.
sb.Insert(pos, String.Format("{2}{0,12:X4} {1,12}{2}", "Code Unit", "Character", "\n"))
|> ignore

// Convert the StringBuilder to a string and display it.
printfn $"{sb}"


// The example displays the following output:
//    ********** Adding Text to a StringBuilder Object **********
//
//    Some code points and their corresponding characters:
//
//       Code Unit    Character
//            0032            2
//            0033            3
//            0034            4
//            0035            5
//            0036            6
//            0037            7
//            0038            8
//            0039            9
//            003A            :
//            003B            ;
//            003C            <
Imports System.Text

Module Example7
    Public Sub Main()
        ' Create a StringBuilder object with no text.
        Dim sb As New StringBuilder()
        ' Append some text.
        sb.Append("*"c, 10).Append(" Adding Text to a StringBuilder Object ").Append("*"c, 10)
        sb.AppendLine()
        sb.AppendLine()
        sb.AppendLine("Some code points and their corresponding characters:")
        ' Append some formatted text.
        For ctr = 50 To 60
            sb.AppendFormat("{0,12:X4} {1,12}", ctr, Convert.ToChar(ctr))
            sb.AppendLine()
        Next
        ' Find the end of the introduction to the column.
        Dim pos As Integer = sb.ToString().IndexOf("characters:") + 11 +
                           Environment.NewLine.Length
        ' Insert a column header.
        sb.Insert(pos, String.Format("{2}{0,12:X4} {1,12}{2}", "Code Unit",
                                   "Character", vbCrLf))

        ' Convert the StringBuilder to a string and display it.      
        Console.WriteLine(sb.ToString())
    End Sub
End Module
' The example displays the following output:
'       ********** Adding Text to a StringBuilder Object **********
'       
'       Some code points and their corresponding characters:
'       
'          Code Unit    Character
'               0032            2
'               0033            3
'               0034            4
'               0035            5
'               0036            6
'               0037            7
'               0038            8
'               0039            9
'               003A            :
'               003B            ;
'               003C            <

Tekst verwijderen uit een StringBuilder-object

De StringBuilder klasse bevat methoden waarmee de grootte van het huidige StringBuilder exemplaar kan worden verkleind. Met de Clear methode worden alle tekens verwijderd en wordt de Length eigenschap ingesteld op nul. Met de Remove methode wordt een opgegeven aantal tekens verwijderd dat begint bij een bepaalde indexpositie. Daarnaast kunt u tekens van het einde van een StringBuilder object verwijderen door de Length eigenschap ervan in te stellen op een waarde die kleiner is dan de lengte van het huidige exemplaar.

In het volgende voorbeeld wordt een deel van de tekst uit een StringBuilder object verwijderd, worden de resulterende waarden voor de capaciteit, de maximale capaciteit en de lengteeigenschap weergegeven. Vervolgens wordt de Clear methode aangeroepen om alle tekens uit het StringBuilder object te verwijderen.

using System;
using System.Text;

public class Example5
{
    public static void Main()
    {
        StringBuilder sb = new StringBuilder("A StringBuilder object");
        ShowSBInfo(sb);
        // Remove "object" from the text.
        string textToRemove = "object";
        int pos = sb.ToString().IndexOf(textToRemove);
        if (pos >= 0)
        {
            sb.Remove(pos, textToRemove.Length);
            ShowSBInfo(sb);
        }
        // Clear the StringBuilder contents.
        sb.Clear();
        ShowSBInfo(sb);
    }

    public static void ShowSBInfo(StringBuilder sb)
    {
        Console.WriteLine($"\nValue: {sb.ToString()}");
        foreach (var prop in sb.GetType().GetProperties())
        {
            if (prop.GetIndexParameters().Length == 0)
                Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
        }
        Console.WriteLine();
    }
}
// The example displays the following output:
//    Value: A StringBuilder object
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 22
//    
//    Value: A StringBuilder
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 16
//    
//    Value:
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 0
open System.Text

let showSBInfo (sb: StringBuilder) =
    for prop in sb.GetType().GetProperties() do
        if prop.GetIndexParameters().Length = 0 then
            printf $"{prop.Name}: {prop.GetValue sb:N0}    "

    printfn ""

let sb = StringBuilder "A StringBuilder object"
showSBInfo sb
// Remove "object" from the text.
let textToRemove = "object"
let pos = (string sb).IndexOf textToRemove

if pos >= 0 then
    sb.Remove(pos, textToRemove.Length) |> ignore
    showSBInfo sb

// Clear the StringBuilder contents.
sb.Clear() |> ignore
showSBInfo sb

// The example displays the following output:
//    Value: A StringBuilder object
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 22
//
//    Value: A StringBuilder
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 16
//
//    Value:
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 0
Imports System.Text

Module Example6
    Public Sub Main()
        Dim sb As New StringBuilder("A StringBuilder object")
        ShowSBInfo(sb)
        ' Remove "object" from the text.
        Dim textToRemove As String = "object"
        Dim pos As Integer = sb.ToString().IndexOf(textToRemove)
        If pos >= 0 Then
            sb.Remove(pos, textToRemove.Length)
            ShowSBInfo(sb)
        End If
        ' Clear the StringBuilder contents.
        sb.Clear()
        ShowSBInfo(sb)
    End Sub

    Public Sub ShowSBInfo(sb As StringBuilder)
        Console.WriteLine()
        Console.WriteLine("Value: {0}", sb.ToString())
        For Each prop In sb.GetType().GetProperties
            If prop.GetIndexParameters().Length = 0 Then
                Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb))
            End If
        Next
        Console.WriteLine()
    End Sub
End Module
' The example displays the following output:
'    Value: A StringBuilder object
'    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 22
'    
'    Value: A StringBuilder
'    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 16
'    
'    Value:
'    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 0

De tekst in een StringBuilder-object wijzigen

De StringBuilder.Replace methode vervangt alle exemplaren van een teken of tekenreeks in het hele StringBuilder object of in een bepaald tekenbereik. In het volgende voorbeeld wordt de Replace methode gebruikt om alle uitroeptekens (!) te vervangen door vraagtekens (?) in het StringBuilder object.

using System;
using System.Text;

public class Example13
{
    public static void Main()
    {
        StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
        MyStringBuilder.Replace('!', '?');
        Console.WriteLine(MyStringBuilder);
    }
}
// The example displays the following output:
//       Hello World?
open System.Text

let myStringBuilder = StringBuilder "Hello World!"
myStringBuilder.Replace('!', '?') |> ignore
printfn $"{myStringBuilder}"

// The example displays the following output:
//       Hello World?
Imports System.Text

Module Example
   Public Sub Main()
      Dim MyStringBuilder As New StringBuilder("Hello World!")
      MyStringBuilder.Replace("!"c, "?"c)
      Console.WriteLine(MyStringBuilder)
   End Sub
End Module
' The example displays the following output:
'       Hello World?

De tekst in een StringBuilder-object doorzoeken

De StringBuilder klasse bevat geen methoden die vergelijkbaar zijn met die van de String.ContainsString.IndexOfString.StartsWithklasse en String methoden waarmee u het object kunt doorzoeken op een bepaald teken of een subtekenreeks. Als u de aanwezigheids- of begintekenpositie van een subtekenreeks bepaalt, moet u een String waarde doorzoeken met behulp van een tekenreekszoekmethode of een reguliere expressiemethode. Er zijn vier manieren om dergelijke zoekopdrachten te implementeren, zoals in de volgende tabel wordt weergegeven.

Techniek Voordelen Nadelen
Zoek tekenreekswaarden voordat u ze toevoegt aan het StringBuilder object. Handig om te bepalen of er een subtekenreeks bestaat. Kan niet worden gebruikt wanneer de indexpositie van een subtekenreeks belangrijk is.
Roep ToString aan en doorzoek het geretourneerde String-object. Eenvoudig te gebruiken als u alle tekst aan een StringBuilder object toewijst en deze vervolgens gaat wijzigen. Omslachtig om herhaaldelijk aan te roepen ToString als u wijzigingen moet aanbrengen voordat alle tekst aan het StringBuilder object wordt toegevoegd.

Vergeet niet om te werken vanaf het einde van de tekst van het StringBuilder object als u wijzigingen aanbrengt.
Gebruik de Chars[Int32] eigenschap om opeenvolgend een reeks tekens te doorzoeken. Handig als u zich bezig houdt met afzonderlijke tekens of een kleine subtekenreeks. Omslachtig als het aantal tekens dat moet worden gezocht groot is of als de zoeklogica complex is.

Resulteert in uiterst slechte prestaties voor objecten die enorm groot zijn geworden via herhaalde methode-aanroepen.
Converteer het StringBuilder object naar een String object en voer wijzigingen uit op het String object. Handig als het aantal wijzigingen klein is. Neutraliseert het prestatievoordeel van de StringBuilder klasse wanneer het aantal wijzigingen groot is.

Laten we deze technieken in meer detail bekijken.

  • Als het doel van de zoekopdracht is om te bepalen of er een bepaalde subtekenreeks bestaat (als u niet geïnteresseerd bent in de positie van de subtekenreeks), kunt u tekenreeksen zoeken voordat u deze opslaat in het StringBuilder object. In het volgende voorbeeld ziet u één mogelijke implementatie. Hiermee wordt de StringBuilderFinder-klasse gedefinieerd waarvan de constructor een verwijzing naar een StringBuilder-object ontvangt en de subtekenreeks die in de tekenreeks moet worden gevonden. In dit geval probeert het voorbeeld te bepalen of geregistreerde temperaturen zich in Fahrenheit of Celsius bevinden en wordt de juiste inleidende tekst toegevoegd aan het begin van het StringBuilder object. Een generator voor willekeurige getallen wordt gebruikt om een matrix te selecteren die gegevens bevat in graden Celsius of graden Fahrenheit.

    using System;
    using System.Text;
    
    public class Example9
    {
        public static void Main()
        {
            Random rnd = new Random();
            string[] tempF = { "47.6F", "51.3F", "49.5F", "62.3F" };
            string[] tempC = { "21.2C", "16.1C", "23.5C", "22.9C" };
            string[][] temps = { tempF, tempC };
    
            StringBuilder sb = new StringBuilder();
            var f = new StringBuilderFinder(sb, "F");
            var baseDate = new DateTime(2013, 5, 1);
            String[] temperatures = temps[rnd.Next(2)];
            bool isFahrenheit = false;
            foreach (var temperature in temperatures)
            {
                if (isFahrenheit)
                    sb.AppendFormat("{0:d}: {1}\n", baseDate, temperature);
                else
                    isFahrenheit = f.SearchAndAppend(String.Format("{0:d}: {1}\n",
                                                     baseDate, temperature));
                baseDate = baseDate.AddDays(1);
            }
            if (isFahrenheit)
            {
                sb.Insert(0, "Average Daily Temperature in Degrees Fahrenheit");
                sb.Insert(47, "\n\n");
            }
            else
            {
                sb.Insert(0, "Average Daily Temperature in Degrees Celsius");
                sb.Insert(44, "\n\n");
            }
            Console.WriteLine(sb.ToString());
        }
    }
    
    public class StringBuilderFinder
    {
        private StringBuilder sb;
        private String text;
    
        public StringBuilderFinder(StringBuilder sb, String textToFind)
        {
            this.sb = sb;
            this.text = textToFind;
        }
    
        public bool SearchAndAppend(String stringToSearch)
        {
            sb.Append(stringToSearch);
            return stringToSearch.Contains(text);
        }
    }
    // The example displays output similar to the following:
    //    Average Daily Temperature in Degrees Celsius
    //    
    //    5/1/2013: 21.2C
    //    5/2/2013: 16.1C
    //    5/3/2013: 23.5C
    //    5/4/2013: 22.9C
    
    open System
    open System.Text
    
    type StringBuilderFinder(sb: StringBuilder, textToFind: string) =
        member _.SearchAndAppend(stringToSearch: string) =
            sb.Append stringToSearch |> ignore
            stringToSearch.Contains textToFind
    
    let tempF = [| "47.6F"; "51.3F"; "49.5F"; "62.3F" |]
    let tempC = [| "21.2C"; "16.1C"; "23.5C"; "22.9C" |]
    let temps = [| tempF; tempC |]
    
    let sb = StringBuilder()
    let f = StringBuilderFinder(sb, "F")
    let temperatures = temps[Random.Shared.Next(2)]
    let mutable baseDate = DateTime(2013, 5, 1)
    let mutable isFahrenheit = false
    
    for temperature in temperatures do
        if isFahrenheit then
            sb.AppendFormat("{0:d}: {1}\n", baseDate, temperature) |> ignore
        else
            isFahrenheit <- $"{baseDate:d}: {temperature}\n" |> f.SearchAndAppend
    
        baseDate <- baseDate.AddDays 1
    
    if isFahrenheit then
        sb.Insert(0, "Average Daily Temperature in Degrees Fahrenheit") |> ignore
        sb.Insert(47, "\n\n") |> ignore
    
    else
        sb.Insert(0, "Average Daily Temperature in Degrees Celsius") |> ignore
        sb.Insert(44, "\n\n") |> ignore
    
    printfn $"{sb}"
    
    // The example displays output similar to the following:
    //    Average Daily Temperature in Degrees Celsius
    //
    //    5/1/2013: 21.2C
    //    5/2/2013: 16.1C
    //    5/3/2013: 23.5C
    //    5/4/2013: 22.9C
    
    Imports System.Text
    
    Module Example9
        Public Sub Main()
            Dim rnd As New Random()
            Dim tempF() As String = {"47.6F", "51.3F", "49.5F", "62.3F"}
            Dim tempC() As String = {"21.2C", "16.1C", "23.5C", "22.9C"}
            Dim temps()() As String = {tempF, tempC}
    
            Dim sb As StringBuilder = New StringBuilder()
            Dim f As New StringBuilderFinder(sb, "F")
            Dim baseDate As New DateTime(2013, 5, 1)
            Dim temperatures() As String = temps(rnd.Next(2))
            Dim isFahrenheit As Boolean = False
            For Each temperature In temperatures
                If isFahrenheit Then
                    sb.AppendFormat("{0:d}: {1}{2}", baseDate, temperature, vbCrLf)
                Else
                    isFahrenheit = f.SearchAndAppend(String.Format("{0:d}: {1}{2}",
                                                 baseDate, temperature, vbCrLf))
                End If
                baseDate = baseDate.AddDays(1)
            Next
            If isFahrenheit Then
                sb.Insert(0, "Average Daily Temperature in Degrees Fahrenheit")
                sb.Insert(47, vbCrLf + vbCrLf)
            Else
                sb.Insert(0, "Average Daily Temperature in Degrees Celsius")
                sb.Insert(44, vbCrLf + vbCrLf)
            End If
            Console.WriteLine(sb.ToString())
        End Sub
    End Module
    
    Public Class StringBuilderFinder
       Private sb As StringBuilder
       Private text As String
       
       Public Sub New(sb As StringBuilder, textToFind As String)
          Me.sb = sb
          text = textToFind
       End Sub
       
       Public Function SearchAndAppend(stringToSearch As String) As Boolean
          sb.Append(stringToSearch)
          Return stringToSearch.Contains(text)
       End Function
    End Class
    ' The example displays output similar to the following:
    '    Average Daily Temperature in Degrees Celsius
    '    
    '    5/1/2013: 21.2C
    '    5/2/2013: 16.1C
    '    5/3/2013: 23.5C
    '    5/4/2013: 22.9C
    
  • Roep de StringBuilder.ToString methode aan om het StringBuilder object te converteren naar een String object. U kunt de tekenreeks doorzoeken met behulp van methoden zoals String.LastIndexOf of String.StartsWith, of u kunt reguliere expressies en de Regex klasse gebruiken om naar patronen te zoeken. Omdat zowel als StringBuilderString objecten UTF-16-codering gebruiken om tekens op te slaan, zijn de indexposities van tekens, subtekenreeksen en reguliere expressieovereenkomsten hetzelfde in beide objecten. Hiermee kunt u methoden gebruiken StringBuilder om wijzigingen aan te brengen op dezelfde positie waarop die tekst in het String object wordt gevonden.

    Notitie

    Als u deze benadering gebruikt, moet u vanaf het einde van het StringBuilder object naar het begin ervan werken, zodat u het StringBuilder object niet herhaaldelijk hoeft te converteren naar een tekenreeks.

    In het volgende voorbeeld ziet u deze benadering. Er worden vier exemplaren opgeslagen van elke letter van het Engelse alfabet in een StringBuilder object. Vervolgens wordt de tekst geconverteerd naar een String object en wordt een reguliere expressie gebruikt om de beginpositie van elke reeks van vier tekens te identificeren. Ten slotte wordt een onderstrepingsteken toegevoegd vóór elke reeks van vier tekens, behalve voor de eerste reeks, en wordt het eerste teken van de reeks geconverteerd naar hoofdletters.

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    
    public class Example10
    {
        public static void Main()
        {
            // Create a StringBuilder object with 4 successive occurrences 
            // of each character in the English alphabet. 
            StringBuilder sb = new StringBuilder();
            for (ushort ctr = (ushort)'a'; ctr <= (ushort)'z'; ctr++)
                sb.Append(Convert.ToChar(ctr), 4);
    
            // Create a parallel string object.
            String sbString = sb.ToString();
            // Determine where each new character sequence begins.
            String pattern = @"(\w)\1+";
            MatchCollection matches = Regex.Matches(sbString, pattern);
    
            // Uppercase the first occurrence of the sequence, and separate it
            // from the previous sequence by an underscore character.
            for (int ctr = matches.Count - 1; ctr >= 0; ctr--)
            {
                Match m = matches[ctr];
                sb[m.Index] = Char.ToUpper(sb[m.Index]);
                if (m.Index > 0) sb.Insert(m.Index, "_");
            }
            // Display the resulting string.
            sbString = sb.ToString();
            int line = 0;
            do
            {
                int nChars = line * 80 + 79 <= sbString.Length ?
                                    80 : sbString.Length - line * 80;
                Console.WriteLine(sbString.Substring(line * 80, nChars));
                line++;
            } while (line * 80 < sbString.Length);
        }
    }
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    open System
    open System.Text
    open System.Text.RegularExpressions
    
    // Create a StringBuilder object with 4 successive occurrences
    // of each character in the English alphabet.
    let sb = StringBuilder()
    
    for char in 'a' .. 'z' do
        sb.Append(char, 4) |> ignore
    
    // Create a parallel string object.
    let sbString = string sb
    // Determine where each new character sequence begins.
    let pattern = @"(\w)\1+"
    let matches = Regex.Matches(sbString, pattern)
    
    // Uppercase the first occurrence of the sequence, and separate it
    // from the previous sequence by an underscore character.
    for i = matches.Count - 1 downto 0 do
        let m = matches[i]
        sb[m.Index] <- Char.ToUpper sb[m.Index]
    
        if m.Index > 0 then
            sb.Insert(m.Index, "_") |> ignore
    
    // Display the resulting string.
    let sbString2 = string sb
    
    for line = 0 to (sbString2.Length - 1) / 80 do
        let nChars =
            if line * 80 + 79 <= sbString2.Length then
                80
            else
                sbString2.Length - line * 80
    
        printfn $"{sbString2.Substring(line * 80, nChars)}"
    
    
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    Imports System.Text
    Imports System.Text.RegularExpressions
    
    Module Example10
        Public Sub Main()
            ' Create a StringBuilder object with 4 successive occurrences 
            ' of each character in the English alphabet. 
            Dim sb As New StringBuilder()
            For ctr As UShort = AscW("a") To AscW("z")
                sb.Append(ChrW(ctr), 4)
            Next
            ' Create a parallel string object.
            Dim sbString As String = sb.ToString()
            ' Determine where each new character sequence begins.
            Dim pattern As String = "(\w)\1+"
            Dim matches As MatchCollection = Regex.Matches(sbString, pattern)
    
            ' Uppercase the first occurrence of the sequence, and separate it
            ' from the previous sequence by an underscore character.
            For ctr As Integer = matches.Count - 1 To 0 Step -1
                Dim m As Match = matches(ctr)
                sb.Chars(m.Index) = Char.ToUpper(sb.Chars(m.Index))
                If m.Index > 0 Then sb.Insert(m.Index, "_")
            Next
            ' Display the resulting string.
            sbString = sb.ToString()
            Dim line As Integer = 0
            Do
                Dim nChars As Integer = If(line * 80 + 79 <= sbString.Length,
                                        80, sbString.Length - line * 80)
                Console.WriteLine(sbString.Substring(line * 80, nChars))
                line += 1
            Loop While line * 80 < sbString.Length
        End Sub
    End Module
    ' The example displays the following output:
    '    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    '    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
  • Gebruik de StringBuilder.Chars[] eigenschap om een reeks tekens in een StringBuilder object opeenvolgend te doorzoeken. Deze benadering is mogelijk niet praktisch als het aantal tekens dat moet worden doorzocht groot is of als de zoeklogica bijzonder complex is. Voor de prestatie-implicaties van op tekens gebaseerde indextoegang voor zeer grote, gesegmenteerde StringBuilder objecten, raadpleeg de documentatie van de StringBuilder.Chars[] eigenschap.

    Het volgende voorbeeld is identiek aan de functionaliteit van het vorige voorbeeld, maar verschilt in de implementatie. De eigenschap wordt gebruikt Chars[Int32] om te detecteren wanneer een tekenwaarde is gewijzigd, een onderstrepingsteken op die positie invoegt en het eerste teken in de nieuwe reeks converteert naar hoofdletters.

    using System;
    using System.Text;
    
    public class Example11
    {
        public static void Main()
        {
            // Create a StringBuilder object with 4 successive occurrences 
            // of each character in the English alphabet. 
            StringBuilder sb = new StringBuilder();
            for (ushort ctr = (ushort)'a'; ctr <= (ushort)'z'; ctr++)
                sb.Append(Convert.ToChar(ctr), 4);
    
            // Iterate the text to determine when a new character sequence occurs.
            int position = 0;
            Char current = '\u0000';
            do
            {
                if (sb[position] != current)
                {
                    current = sb[position];
                    sb[position] = Char.ToUpper(sb[position]);
                    if (position > 0)
                        sb.Insert(position, "_");
                    position += 2;
                }
                else
                {
                    position++;
                }
            } while (position <= sb.Length - 1);
            // Display the resulting string.
            String sbString = sb.ToString();
            int line = 0;
            do
            {
                int nChars = line * 80 + 79 <= sbString.Length ?
                                    80 : sbString.Length - line * 80;
                Console.WriteLine(sbString.Substring(line * 80, nChars));
                line++;
            } while (line * 80 < sbString.Length);
        }
    }
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    open System
    open System.Text
    
    // Create a StringBuilder object with 4 successive occurrences
    // of each character in the English alphabet.
    let sb = StringBuilder()
    
    for char in 'a' .. 'z' do
        sb.Append(char, 4) |> ignore
    
    // Iterate the text to determine when a new character sequence occurs.
    let mutable position = 0
    let mutable current = '\u0000'
    
    while position <= sb.Length - 1 do
        if sb[position] <> current then
            current <- sb[position]
            sb[position] <- Char.ToUpper sb[position]
    
            if position > 0 then
                sb.Insert(position, "_") |> ignore
    
            position <- position + 2
    
        else
            position <- position + 1
    
    // Display the resulting string.
    let sbString = string sb
    
    for line = 0 to (sbString.Length - 1) / 80 do
        let nChars =
            if line * 80 + 79 <= sbString.Length then
                80
            else
                sbString.Length - line * 80
    
        printfn $"{sbString.Substring(line * 80, nChars)}"
    
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    Imports System.Text
    
    Module Example11
        Public Sub Main()
            ' Create a StringBuilder object with 4 successive occurrences 
            ' of each character in the English alphabet. 
            Dim sb As New StringBuilder()
            For ctr As UShort = AscW("a") To AscW("z")
                sb.Append(ChrW(ctr), 4)
            Next
            ' Iterate the text to determine when a new character sequence occurs.
            Dim position As Integer = 0
            Dim current As Char = ChrW(0)
            Do
                If sb(position) <> current Then
                    current = sb(position)
                    sb(position) = Char.ToUpper(sb(position))
                    If position > 0 Then sb.Insert(position, "_")
                    position += 2
                Else
                    position += 1
                End If
            Loop While position <= sb.Length - 1
            ' Display the resulting string.
            Dim sbString As String = sb.ToString()
            Dim line As Integer = 0
            Do
                Dim nChars As Integer = If(line * 80 + 79 <= sbString.Length,
                                        80, sbString.Length - line * 80)
                Console.WriteLine(sbString.Substring(line * 80, nChars))
                line += 1
            Loop While line * 80 < sbString.Length
        End Sub
    End Module
    ' The example displays the following output:
    '    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    '    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
  • Sla alle ongewijzigde tekst in het StringBuilder object op, roep de StringBuilder.ToString methode aan om het StringBuilder object te converteren naar een String object en voer de wijzigingen in het String object uit. U kunt deze methode gebruiken als u slechts enkele wijzigingen hebt; anders kunnen de kosten voor het werken met onveranderbare tekenreeksen de prestatievoordelen van het gebruik van een StringBuilder object ontkennen.

    Het volgende voorbeeld is identiek aan de functionaliteit van de vorige twee voorbeelden, maar verschilt in de implementatie. Er wordt een StringBuilder object gemaakt, geconverteerd naar een String object en vervolgens een reguliere expressie gebruikt om alle resterende wijzigingen in de tekenreeks uit te voeren. De Regex.Replace(String, String, MatchEvaluator) methode gebruikt een lambda-expressie om de vervanging op elke overeenkomst uit te voeren.

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    
    public class Example12
    {
        public static void Main()
        {
            // Create a StringBuilder object with 4 successive occurrences 
            // of each character in the English alphabet. 
            StringBuilder sb = new StringBuilder();
            for (ushort ctr = (ushort)'a'; ctr <= (ushort)'z'; ctr++)
                sb.Append(Convert.ToChar(ctr), 4);
    
            // Convert it to a string.
            String sbString = sb.ToString();
    
            // Use a regex to uppercase the first occurrence of the sequence, 
            // and separate it from the previous sequence by an underscore.
            string pattern = @"(\w)(\1+)";
            sbString = Regex.Replace(sbString, pattern,
                                     m => (m.Index > 0 ? "_" : "") +
                                     m.Groups[1].Value.ToUpper() +
                                     m.Groups[2].Value);
    
            // Display the resulting string.
            int line = 0;
            do
            {
                int nChars = line * 80 + 79 <= sbString.Length ?
                                    80 : sbString.Length - line * 80;
                Console.WriteLine(sbString.Substring(line * 80, nChars));
                line++;
            } while (line * 80 < sbString.Length);
        }
    }
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    open System.Text
    open System.Text.RegularExpressions
    
    // Create a StringBuilder object with 4 successive occurrences
    // of each character in the English alphabet.
    let sb = StringBuilder()
    
    for char in 'a' .. 'z' do
        sb.Append(char, 4) |> ignore
    
    // Convert it to a string.
    let sbString = string sb
    
    // Use a regex to uppercase the first occurrence of the sequence,
    // and separate it from the previous sequence by an underscore.
    let pattern = @"(\w)(\1+)"
    
    let sbStringReplaced =
        Regex.Replace(
            sbString,
            pattern,
            fun m ->
                (if m.Index > 0 then "_" else "")
                + m.Groups[ 1 ].Value.ToUpper()
                + m.Groups[2].Value
        )
    
    // Display the resulting string.
    for line = 0 to (sbStringReplaced.Length - 1) / 80 do
        let nChars =
            if line * 80 + 79 <= sbStringReplaced.Length then
                80
            else
                sbStringReplaced.Length - line * 80
    
        printfn $"{sbStringReplaced.Substring(line * 80, nChars)}"
    
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    Imports System.Text
    Imports System.Text.RegularExpressions
    
    Module Example12
        Public Sub Main()
            ' Create a StringBuilder object with 4 successive occurrences 
            ' of each character in the English alphabet. 
            Dim sb As New StringBuilder()
            For ctr As UShort = AscW("a") To AscW("z")
                sb.Append(ChrW(ctr), 4)
            Next
            ' Convert it to a string.
            Dim sbString As String = sb.ToString()
    
            ' Use a regex to uppercase the first occurrence of the sequence, 
            ' and separate it from the previous sequence by an underscore.
            Dim pattern As String = "(\w)(\1+)"
            sbString = Regex.Replace(sbString, pattern,
                                   Function(m) If(m.Index > 0, "_", "") +
                                               m.Groups(1).Value.ToUpper +
                                               m.Groups(2).Value)
    
            ' Display the resulting string.
            Dim line As Integer = 0
            Do
                Dim nChars As Integer = If(line * 80 + 79 <= sbString.Length,
                                        80, sbString.Length - line * 80)
                Console.WriteLine(sbString.Substring(line * 80, nChars))
                line += 1
            Loop While line * 80 < sbString.Length
        End Sub
    End Module
    ' The example displays the following output:
    '    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    '    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    

Het StringBuilder-object converteren naar een tekenreeks

U moet het StringBuilder object converteren naar een String object voordat u de tekenreeks die door het StringBuilder object wordt vertegenwoordigd, kunt doorgeven aan een methode met een String parameter of deze in de gebruikersinterface kunt weergeven. U voert deze conversie uit door de StringBuilder.ToString-methode aan te roepen. Zie voor een afbeelding het vorige voorbeeld, waarmee de ToString methode wordt aangeroepen om een StringBuilder object te converteren naar een tekenreeks, zodat het kan worden doorgegeven aan een reguliere expressiemethode.