.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.Create 與 new 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。