共用方式為


在 .NET 中建立新的字串

.NET 允許使用簡單指派來建立字串,而且也會多載類別建構函式,以支援使用數個不同的參數建立字串。 .NET 也會在 類別中 System.String 提供數種方法,藉由結合數個字串、字串陣列或物件,來建立新的字串物件。

使用指派建立字串

建立新 String 物件最簡單的方式就是將字串常值指派給 String 物件。

使用類別建構函式建立字串

您可以使用 String 類別建構函式的多載來從字元陣列建立字串。 您也可以藉由複製指定次數的特定字元來建立新的字串。 String(ReadOnlySpan<Char>) 建構子過載能夠接受一個 ReadOnlySpan<T> 或由堆疊分配的 Span<T> 字元,這樣在建立已知大小的小字串時,可避免在管理堆積中分配中間字元陣列,儘管最後的字串實例仍然會分配在管理堆積中。

傳回字串的方法

下表列出數個傳回新字串對象的實用方法。

方法名稱 使用
String.Format 從一組輸入物件建置格式化字串。
String.Concat 從兩個或多個字串建置字串。
String.Join 結合字串陣列來建立一個新的字串。
String.Insert 在現有字串的指定索引處插入一段字串,以建立新的字串。
String.CopyTo 將字串中的指定字元複製到字元陣列中指定的位置。
String.Create 建立一個具有指定長度的新字串,透過回調函數來填充字元,該回調函數接收一個可寫入的 Span<T> 和由呼叫者提供的狀態物件。

String.Format

您可以使用 String.Format 方法來建立格式化字串,並串連代表多個物件的字串。 這個方法會自動將任何傳遞的物件轉換成字串。 例如,如果您的應用程式必須向用戶顯示 Int32 值和 DateTime 值,您可以輕鬆地建構字串,以使用 Format 方法來表示這些值。 如需與此方法搭配使用之格式設定慣例的詳細資訊,請參閱 複合格式設定一節。

使用 Format 方法來建立使用整數變數的字串的範例如下。

int numberOfFleas = 12;
string miscInfo = String.Format("Your dog has {0} fleas. " +
                                "It is time to get a flea collar. " +
                                "The current universal date is: {1:u}.",
                                numberOfFleas, DateTime.Now);
Console.WriteLine(miscInfo);
// The example displays the following output:
//       Your dog has 12 fleas. It is time to get a flea collar.
//       The current universal date is: 2008-03-28 13:31:40Z.
Dim numberOfFleas As Integer = 12
Dim miscInfo As String = String.Format("Your dog has {0} fleas. " & _
                                       "It is time to get a flea collar. " & _
                                       "The current universal date is: {1:u}.", _
                                       numberOfFleas, Date.Now)
Console.WriteLine(miscInfo)
' The example displays the following output:
'       Your dog has 12 fleas. It is time to get a flea collar. 
'       The current universal date is: 2008-03-28 13:31:40Z.

在此範例中,DateTime.Now 會依據當前執行緒的文化設定來顯示目前的日期與時間。

String.Concat

String.Concat方法可用來從兩個或多個現有物件輕鬆建立新的字串物件。 它提供與語言無關的方式來串連字串。 此方法接受衍生自 System.Object的任何類別。 下列範例會從兩個現有的字串物件和分隔字元建立字串。

string helloString1 = "Hello";
string helloString2 = "World!";
Console.WriteLine(String.Concat(helloString1, ' ', helloString2));
// The example displays the following output:
//      Hello World!
Dim helloString1 As String = "Hello"
Dim helloString2 As String = "World!"
Console.WriteLine(String.Concat(helloString1, " "c, helloString2))
' The example displays the following output:
'      Hello World!

String.Join

方法 String.Join 會從字串陣列和分隔符字串建立新的字串。 如果您想要將多個字串串連在一起,讓清單可能以逗號分隔,這個方法會很有用。

下列範例會使用空格來系結字串陣列。

string[] words = {"Hello", "and", "welcome", "to", "my" , "world!"};
Console.WriteLine(String.Join(" ", words));
// The example displays the following output:
//      Hello and welcome to my world!
Dim words() As String = {"Hello", "and", "welcome", "to", "my", "world!"}
Console.WriteLine(String.Join(" ", words))
' The example displays the following output:
'      Hello and welcome to my world!

String.Insert

方法 String.Insert 會將字串插入另一個字串中指定的位置,藉以建立新的字串。 此方法使用以零起始的索引。 下列範例會將字串插入MyString的第五個索引位置,並建立具有此值的新字串。

string sentence = "Once a time.";
 Console.WriteLine(sentence.Insert(4, " upon"));
 // The example displays the following output:
 //      Once upon a time.
Dim sentence As String = "Once a time."
Console.WriteLine(sentence.Insert(4, " upon"))
' The example displays the following output:
'      Once upon a time.

String.CopyTo

方法 String.CopyTo 會將字串的部分複製到字元陣列。 您可以同時指定字串的開頭索引和要複製的字元數。 此方法會採用來源索引、字元陣列、目標索引,以及要複製的字元數量。 所有索引都是以零起始的。

下列範例會使用CopyTo方法,將字串物件中的字元「Hello」複製到字元陣列的第一個位置。

string greeting = "Hello World!";
char[] charArray = {'W','h','e','r','e'};
Console.WriteLine($"The original character array: {new string(charArray)}");
greeting.CopyTo(0, charArray,0 ,5);
Console.WriteLine($"The new character array: {new string(charArray)}");
// The example displays the following output:
//       The original character array: Where
//       The new character array: Hello
Dim greeting As String = "Hello World!"
Dim charArray() As Char = {"W"c, "h"c, "e"c, "r"c, "e"c}
Console.WriteLine("The original character array: {0}", New String(charArray))
greeting.CopyTo(0, charArray, 0, 5)
Console.WriteLine("The new character array: {0}", New String(charArray))
' The example displays the following output:
'       The original character array: Where
'       The new character array: Hello

String.Create

這個 String.Create 方法允許你用回調方式程式化填滿新字串的字元。 回調會接收一個可用於寫入字元的Span<T>以及呼叫者提供的狀態物件,這樣你可以在不分配中間字元緩衝區的情況下建立字串內容。 回調本身仍可能進行分配,例如捕捉區域變數或呼叫其他內存分配密集的 API。

以下範例用 String.Create 來從連續字母表字元組成一個五字元的字串:

string result = string.Create(5, 'a', (span, firstChar) =>
{
    for (int i = 0; i < span.Length; i++)
    {
        span[i] = (char)(firstChar + i);
    }
});

Console.WriteLine(result); // abcde
Module Program
    Sub Main()
        Dim result As String = String.Create(5, "a"c, Sub(span, firstChar)
                                                           For i As Integer = 0 To span.Length - 1
                                                               span(i) = ChrW(AscW(firstChar) + i)
                                                           Next
                                                       End Sub)

        Console.WriteLine(result) ' abcde
    End Sub
End Module

String.Create 設計用於對效能敏感的情境,當你事先知道最終字串長度,並希望避免分配中間字元緩衝區時。 執行時會分配一個新字串,將其後備緩衝區直接以Span<char>的形式傳送給你的回調,並在回調返回後傳回不可變字串。 回撥完成後,資料不再複製。

String.Createnew String(Span<char>)

另一個有效率建構字串的選項是配置一個字元緩衝區,將其填滿,然後傳給 String(ReadOnlySpan<char>) 建構子:

static string CreateStringFromSpan()
{
    Span<char> span = stackalloc char[5];
    for (int i = 0; i < 5; i++)
    {
        span[i] = (char)('a' + i);
    }
    return new string(span);
}

Console.WriteLine(CreateStringFromSpan()); // abcde

兩種方法都只分配最後一個字串一次。 主要差異包括:

  • stackalloc + new string(span) 將工作緩衝區放在堆疊上。 這對於 小型固定大小 緩衝區來說最快,但堆疊是有限資源;大或深度巢狀配置可能導致 StackOverflowException。 此範例展示了 C# stackalloc 模式;Visual Basic 不支援 stackalloc,但當你有 String(ReadOnlySpan<char>)時,仍然可以呼叫建構子。ReadOnlySpan<char>
  • String.Create 將堆積上的工作緩衝區分配為字串物件本身的一部分,因此沒有堆疊壓力。 它也接受一個已指定型別的狀態參數,執行時會將該參數傳給你的回調函式,且不會進行裝箱,這避免了當狀態是參考型別或未捕獲的結構體時進行裝箱配置。 一般而言,偏好 stackalloc + new String(span) 小字串(通常少於幾百個字元)且大小已知且有界。 當需要考量大小、避免堆疊運行壓力,或是在將狀態傳入回調時避免物件封裝,請使用 String.Create

另請參閱