diff --git a/docs/standard/base-types/creating-new.md b/docs/standard/base-types/creating-new.md index 6cd9906e023a7..fe52b5cb10791 100644 --- a/docs/standard/base-types/creating-new.md +++ b/docs/standard/base-types/creating-new.md @@ -1,7 +1,8 @@ --- title: "Creating New Strings" description: Learn to create strings using assignment, class constructors, or System.String methods that combine several strings, arrays of strings, or objects in .NET. -ms.date: "03/30/2017" +ms.date: "03/16/2026" +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -12,6 +13,7 @@ helpviewer_keywords: - "Concat method" - "strings [.NET], creating" - "Insert method" + - "Create method" --- # Create new strings in .NET @@ -19,66 +21,91 @@ helpviewer_keywords: ## Create strings using assignment - The easiest way to create a new object is simply to assign a string literal to a object. +The easiest way to create a new object is simply to assign a string literal to a object. ## Create strings using a class constructor - You can use overloads of the class constructor to create strings from character arrays. You can also create a new string by duplicating a particular character a specified number of times. +You can use overloads of the class constructor to create strings from character arrays. You can also create a new string by duplicating a particular character a specified number of times. The constructor overload accepts a or a stack-allocated of characters and avoids allocating an intermediate character array on the managed heap when you build small strings of a known size, although the resulting string instance is still allocated on the managed heap. ## Methods that return strings - The following table lists several useful methods that return new string objects. +The following table lists several useful methods that return new string objects. -| Method name | Use | -|-------------------------------------------------------------|--------------------------------------------------------| -| | Builds a formatted string from a set of input objects. | -| | Builds strings from two or more strings. | -| | Builds a new string by combining an array of strings. | -| | Builds a new string by inserting a string into the specified index of an existing string. | -| | Copies specified characters in a string into a specified position in an array of characters. | +| Method name | Use | +|---------------------------------------------------------------|--------------------------------------------------------| +| | Builds a formatted string from a set of input objects. | +| | Builds strings from two or more strings. | +| | Builds a new string by combining an array of strings. | +| | Builds a new string by inserting a string into the specified index of an existing string. | +| | Copies specified characters in a string into a specified position in an array of characters. | +| | Creates a new string of a specified length, populating characters via a callback that receives a writable and a caller-supplied state object. | ### Format - You can use the `String.Format` method to create formatted strings and concatenate strings representing multiple objects. This method automatically converts any passed object into a string. For example, if your application must display an `Int32` value and a `DateTime` value to the user, you can easily construct a string to represent these values using the `Format` method. For information about formatting conventions used with this method, see the section on [composite formatting](composite-formatting.md). +You can use the `String.Format` method to create formatted strings and concatenate strings representing multiple objects. This method automatically converts any passed object into a string. For example, if your application must display an `Int32` value and a `DateTime` value to the user, you can easily construct a string to represent these values using the `Format` method. For information about formatting conventions used with this method, see the section on [composite formatting](composite-formatting.md). - The following example uses the `Format` method to create a string that uses an integer variable. +The following example uses the `Format` method to create a string that uses an integer variable. - [!code-csharp[Strings.Creating#1](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#1)] - [!code-vb[Strings.Creating#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#1)] +[!code-csharp[Strings.Creating#1](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#1)] +[!code-vb[Strings.Creating#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#1)] - In this example, displays the current date and time in a manner specified by the culture associated with the current thread. +In this example, displays the current date and time in a manner specified by the culture associated with the current thread. ### Concat - The `String.Concat` method can be used to easily create a new string object from two or more existing objects. It provides a language-independent way to concatenate strings. This method accepts any class that derives from `System.Object`. The following example creates a string from two existing string objects and a separating character. +The `String.Concat` method can be used to easily create a new string object from two or more existing objects. It provides a language-independent way to concatenate strings. This method accepts any class that derives from `System.Object`. The following example creates a string from two existing string objects and a separating character. - [!code-csharp[Strings.Creating#2](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#2)] - [!code-vb[Strings.Creating#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#2)] +[!code-csharp[Strings.Creating#2](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#2)] +[!code-vb[Strings.Creating#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#2)] ### Join - The `String.Join` method creates a new string from an array of strings and a separator string. This method is useful if you want to concatenate multiple strings together, making a list perhaps separated by a comma. +The `String.Join` method creates a new string from an array of strings and a separator string. This method is useful if you want to concatenate multiple strings together, making a list perhaps separated by a comma. - The following example uses a space to bind a string array. +The following example uses a space to bind a string array. - [!code-csharp[Strings.Creating#3](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#3)] - [!code-vb[Strings.Creating#3](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#3)] +[!code-csharp[Strings.Creating#3](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#3)] +[!code-vb[Strings.Creating#3](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#3)] ### Insert - The `String.Insert` method creates a new string by inserting a string into a specified position in another string. This method uses a zero-based index. The following example inserts a string into the fifth index position of `MyString` and creates a new string with this value. +The `String.Insert` method creates a new string by inserting a string into a specified position in another string. This method uses a zero-based index. The following example inserts a string into the fifth index position of `MyString` and creates a new string with this value. - [!code-csharp[Strings.Creating#4](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#4)] - [!code-vb[Strings.Creating#4](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#4)] +[!code-csharp[Strings.Creating#4](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#4)] +[!code-vb[Strings.Creating#4](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#4)] ### CopyTo - The `String.CopyTo` method copies portions of a string into an array of characters. You can specify both the beginning index of the string and the number of characters to be copied. This method takes the source index, an array of characters, the destination index, and the number of characters to copy. All indexes are zero-based. +The `String.CopyTo` method copies portions of a string into an array of characters. You can specify both the beginning index of the string and the number of characters to be copied. This method takes the source index, an array of characters, the destination index, and the number of characters to copy. All indexes are zero-based. - The following example uses the `CopyTo` method to copy the characters of the word "Hello" from a string object to the first index position of an array of characters. +The following example uses the `CopyTo` method to copy the characters of the word "Hello" from a string object to the first index position of an array of characters. - [!code-csharp[Strings.Creating#5](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#5)] - [!code-vb[Strings.Creating#5](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#5)] +[!code-csharp[Strings.Creating#5](../../../samples/snippets/csharp/VS_Snippets_CLR/Strings.Creating/cs/Example.cs#5)] +[!code-vb[Strings.Creating#5](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Strings.Creating/vb/Example.vb#5)] + +### Create + +The method lets you programmatically fill a new string's characters using a callback. The callback receives a writable of characters and a caller-supplied state object, so you can build the string's content without allocating intermediate character buffers. The callback itself might still allocate, for example if it captures local variables or calls other allocation-heavy APIs. + +The following example uses `String.Create` to build a five-character string from consecutive alphabet characters: + +:::code language="csharp" source="./snippets/creating-new/csharp/Program.cs" id="UsingStringCreate"::: +:::code language="vb" source="./snippets/creating-new/vb/Program.vb" id="UsingStringCreate"::: + +`string.Create` is designed for performance-sensitive scenarios where you know the final string length in advance and want to avoid allocating intermediate character buffers. The runtime allocates a new string, passes its backing buffer directly to your callback as a `Span`, and returns the immutable string once the callback returns. No copy of the data occurs after the callback completes. + +#### string.Create vs. new string(Span\) + +Another option for building strings efficiently is to allocate a character buffer with `stackalloc`, fill it, and pass it to the `string(ReadOnlySpan)` constructor: + +:::code language="csharp" source="./snippets/creating-new/csharp/Program.cs" id="UsingSpanConstructor"::: + +Both approaches allocate the final string exactly once. The key differences are: + +- **`stackalloc` + `new string(span)`** places the working buffer on the stack. This is fastest for *small, fixed-size* buffers, but the stack is a finite resource; large or deeply nested allocations can cause a `StackOverflowException`. This example shows the C# `stackalloc` pattern; Visual Basic doesn't support `stackalloc`, but it can still call the `string(ReadOnlySpan)` constructor when you have a `ReadOnlySpan`. +- **`string.Create`** allocates the working buffer on the heap as part of the string object itself, so there's no stack pressure. It also accepts a typed state parameter that the runtime passes to your callback without boxing, avoiding boxing allocations when the state is a reference type or a non-captured struct. + +In general, prefer `stackalloc` + `new string(span)` for small strings (typically fewer than a few hundred characters) with a known, bounded size. Use `string.Create` when the size might be large, when you want to avoid stack pressure, or when passing state into the callback without boxing. ## See also diff --git a/docs/standard/base-types/snippets/creating-new/csharp/Program.cs b/docs/standard/base-types/snippets/creating-new/csharp/Program.cs new file mode 100644 index 0000000000000..4ef617dfa64b7 --- /dev/null +++ b/docs/standard/base-types/snippets/creating-new/csharp/Program.cs @@ -0,0 +1,28 @@ +using System; + +// +static string CreateStringFromSpan() +{ + Span span = stackalloc char[5]; + for (int i = 0; i < 5; i++) + { + span[i] = (char)('a' + i); + } + return new string(span); +} + +Console.WriteLine(CreateStringFromSpan()); // abcde +// + +// +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 +// + diff --git a/docs/standard/base-types/snippets/creating-new/csharp/creating-new.csproj b/docs/standard/base-types/snippets/creating-new/csharp/creating-new.csproj new file mode 100644 index 0000000000000..f5599093400c6 --- /dev/null +++ b/docs/standard/base-types/snippets/creating-new/csharp/creating-new.csproj @@ -0,0 +1,11 @@ + + + + Exe + net10.0 + creating_new + enable + enable + + + diff --git a/docs/standard/base-types/snippets/creating-new/vb/Program.vb b/docs/standard/base-types/snippets/creating-new/vb/Program.vb new file mode 100644 index 0000000000000..f9526c6763620 --- /dev/null +++ b/docs/standard/base-types/snippets/creating-new/vb/Program.vb @@ -0,0 +1,15 @@ +Imports System + +' +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 +' diff --git a/docs/standard/base-types/snippets/creating-new/vb/creating-new.vbproj b/docs/standard/base-types/snippets/creating-new/vb/creating-new.vbproj new file mode 100644 index 0000000000000..cc8f63307ca35 --- /dev/null +++ b/docs/standard/base-types/snippets/creating-new/vb/creating-new.vbproj @@ -0,0 +1,10 @@ + + + + Exe + creating_new + net10.0 + on + + +