Skip to content

Commit 6538ee8

Browse files
authored
Merge pull request #5822 from MicrosoftDocs/master637348360244851713
For protected CLA branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents 7694d1a + c0745a7 commit 6538ee8

File tree

5 files changed

+134
-1
lines changed

5 files changed

+134
-1
lines changed

docs/code-quality/ca1834.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
title: "CA1834: Use StringBuilder.Append(char) for single character strings"
3+
ms.date: 08/04/2020
4+
ms.topic: reference
5+
f1_keywords:
6+
- "UseStringBuilderAppendChar"
7+
- "CA1834"
8+
helpviewer_keywords:
9+
- "UseStringBuilderAppendChar"
10+
- "CA1834"
11+
author: pgovind
12+
ms.author: prgovi
13+
manager: jeffhand
14+
ms.workload:
15+
- "multiple"
16+
---
17+
# CA1834: Use StringBuilder.Append(char) for single character strings
18+
19+
|Item|Value|
20+
|-|-|
21+
|CheckId|CA1834|
22+
|Category|Microsoft.Performance|
23+
|Breaking change|Non-breaking|
24+
25+
## Cause
26+
27+
This rule fires when a unit length string is passed to the <xref:System.Text.StringBuilder.Append%2A> method.
28+
29+
## Rule description
30+
31+
When calling `StringBuilder.Append` with a unit length string, consider using a `const char` rather than a unit length `const string` to improve performance.
32+
33+
## How to fix violations
34+
35+
The violation can either be fixed manually, or, in some cases, using Quick Actions to fix code in Visual Studio. Examples:
36+
37+
##### Example 1
38+
Invocations of `StringBuilder.Append` with a string literal of unit length:
39+
```csharp
40+
using System;
41+
using System.Text;
42+
43+
namespace TestNamespace
44+
{
45+
class TestClass
46+
{
47+
private void TestMethod()
48+
{
49+
StringBuilder sb = new StringBuilder();
50+
sb.Append("a");
51+
}
52+
}
53+
}
54+
```
55+
> [!TIP]
56+
> A code fix is available for this rule in Visual Studio. To use it, position the cursor on the violation and press **Ctrl**+**.** (period). Choose **Consider using 'StringBuilder.Append(char)' when applicable.** from the list of options that is presented.
57+
>
58+
> ![Code fix for CA1834 - Use StringBuilder.Append(char) for single character strings](media/ca1834-codefix.png)
59+
60+
##### Fix applied by Visual Studio
61+
```csharp
62+
using System;
63+
using System.Text;
64+
65+
namespace TestNamespace
66+
{
67+
class TestClass
68+
{
69+
private void TestMethod()
70+
{
71+
StringBuilder sb = new StringBuilder();
72+
sb.Append('a');
73+
}
74+
}
75+
}
76+
```
77+
78+
In some cases, for example when using a unit length `const string` class field, a code-fix is not suggested by Visual Studio (but the analyzer still fires). These instances require a manual fix.
79+
80+
##### Example 2
81+
Invocations of `StringBuilder.Append` with a `const string` class field of unit length:
82+
```cs
83+
using System;
84+
using System.Text;
85+
86+
namespace TestNamespace
87+
{
88+
public class Program
89+
{
90+
public const string unitString = "a";
91+
92+
static void Main(string[] args)
93+
{
94+
StringBuilder sb = new StringBuilder();
95+
sb.Append(unitString);
96+
}
97+
}
98+
}
99+
```
100+
After careful analysis, `unitString` here can be changed to a `char` without causing any build errors.
101+
102+
##### Fix
103+
```cs
104+
using System;
105+
using System.Text;
106+
107+
namespace TestNamespace
108+
{
109+
public class Program
110+
{
111+
public const char unitString = 'a';
112+
113+
static void Main(string[] args)
114+
{
115+
StringBuilder sb = new StringBuilder();
116+
sb.Append(unitString);
117+
}
118+
}
119+
}
120+
```
121+
122+
## When to suppress warnings
123+
124+
It's safe to suppress a violation of this rule if you're not concerned about improving performance when using `StringBuilder`.
125+
126+
## See also
127+
128+
- [Performance warnings](../code-quality/performance-warnings.md)

docs/code-quality/code-analysis-warnings-for-managed-code-by-checkid.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ f1_keywords:
172172
- CA1831
173173
- CA1832
174174
- CA1833
175+
- CA1834
175176
- CA1835
176177
- CA1836
177178
- CA1837
@@ -463,7 +464,8 @@ The following table lists Code Analysis warnings for managed code by the CheckId
463464
| CA1831 |[CA1831: Use AsSpan instead of Range-based indexers for string when appropriate](../code-quality/ca1831.md) | When using a range-indexer on a string and implicitly assigning the value to ReadOnlySpan&lt;char&gt; type, the method <xref:System.String.Substring%2A?#System_String_Substring_System_Int32_System_Int32_> will be used instead of <xref:System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_>, which produces a copy of requested portion of the string. |
464465
| CA1832 |[CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array](../code-quality/ca1832.md) | When using a range-indexer on an array and implicitly assigning the value to a <xref:System.ReadOnlySpan%601> or <xref:System.ReadOnlyMemory%601> type, the method <xref:System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray%2A> will be used instead of <xref:System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_>, which produces a copy of requested portion of the array. |
465466
| CA1833 |[CA1833: Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array](../code-quality/ca1833.md) | When using a range-indexer on an array and implicitly assigning the value to a <xref:System.Span%601> or <xref:System.Memory%601> type, the method <xref:System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray%2A> will be used instead of <xref:System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_>, which produces a copy of requested portion of the array. |
466-
| CA1835 |[CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'](../code-quality/ca1835.md) | 'Stream' has a 'ReadAsync' overload that takes a 'Memory&lt;Byte&gt;' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory&lt;Byte&gt;' as the first argument. Prefer calling the memory-based overloads, which are more efficient. |
467+
| CA1834 |[CA1834: Use StringBuilder.Append(char) for single character strings](../code-quality/ca1834.md) | <xref:System.Text.StringBuilder> has an `Append` overload that takes a `char` as its argument. Prefer calling the `char` overload for performance reasons. |
468+
| CA1835 |[CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'](../code-quality/ca1835.md) | 'Stream' has a 'ReadAsync' overload that takes a 'Memory&lt;Byte&gt;' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory&lt;Byte&gt;' as the first argument. Prefer calling the memory based overloads, which are more efficient. |
467469
| CA1836 |[CA1836: Prefer `IsEmpty` over `Count` when available](../code-quality/ca1836.md) | Prefer `IsEmpty` property that is more efficient than `Count`, `Length`, <xref:System.Linq.Enumerable.Count%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> or <xref:System.Linq.Enumerable.LongCount%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> to determine whether the object contains or not any items. |
468470
| CA1837 | [CA1837: Use `Environment.ProcessId` instead of `Process.GetCurrentProcess().Id`](../code-quality/ca1837.md) | `Environment.ProcessId` is simpler and faster than `Process.GetCurrentProcess().Id`. |
469471
| CA1838 | [CA1838: Avoid `StringBuilder` parameters for P/Invokes](../code-quality/ca1838.md) | Marshaling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshaling operation. |
62.5 KB
Loading

docs/code-quality/performance-warnings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Performance warnings support high-performance libraries and applications.
5252
| [CA1831: Use AsSpan instead of Range-based indexers for string when appropriate](../code-quality/ca1831.md) | When using a range-indexer on a string and implicitly assigning the value to a ReadOnlySpan&lt;char&gt; type, the method <xref:System.String.Substring%2A?#System_String_Substring_System_Int32_System_Int32_> will be used instead of <xref:System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_>, which produces a copy of requested portion of the string. |
5353
| [CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array](../code-quality/ca1832.md) | When using a range-indexer on an array and implicitly assigning the value to a <xref:System.ReadOnlySpan%601> or <xref:System.ReadOnlyMemory%601> type, the method <xref:System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray%2A> will be used instead of <xref:System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_>, which produces a copy of requested portion of the array. |
5454
| [CA1833: Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array](../code-quality/ca1833.md) | When using a range-indexer on an array and implicitly assigning the value to a <xref:System.Span%601> or <xref:System.Memory%601> type, the method <xref:System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray%2A> will be used instead of <xref:System.Span%601.Slice%2A?#System_Span_1_Slice_System_Int32_System_Int32_>, which produces a copy of requested portion of the array. |
55+
| [CA1834: Use StringBuilder.Append(char) for single character strings](../code-quality/ca1834.md) | <xref:System.Text.StringBuilder> has an `Append` overload that takes a `char` as its argument. Prefer calling the `char` overload to improve performance. |
5556
| [CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'](../code-quality/ca1835.md) | 'Stream' has a 'ReadAsync' overload that takes a 'Memory&lt;Byte&gt;' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory&lt;Byte&gt;' as the first argument. Prefer calling the memory based overloads, which are more efficient. |
5657
| [CA1836: Prefer `IsEmpty` over `Count` when available](../code-quality/ca1836.md) | Prefer `IsEmpty` property that is more efficient than `Count`, `Length`, <xref:System.Linq.Enumerable.Count%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> or <xref:System.Linq.Enumerable.LongCount%60%601%28System.Collections.Generic.IEnumerable%7B%60%600%7D%29> to determine whether the object contains or not any items. |
5758
| [CA1837: Use `Environment.ProcessId` instead of `Process.GetCurrentProcess().Id`](../code-quality/ca1837.md) | `Environment.ProcessId` is simpler and faster than `Process.GetCurrentProcess().Id`. |

docs/code-quality/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@
567567
href: ca1832.md
568568
- name: "CA1833: Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array"
569569
href: ca1833.md
570+
- name: "CA1834: Use StringBuilder.Append(char) for single character strings"
571+
href: ca1834.md
570572
- name: "CA1835: Prefer the memory overloads of Stream ReadAsync/WriteAsync methods"
571573
href: ca1835.md
572574
- name: "CA1836: Prefer IsEmpty over Count when available"

0 commit comments

Comments
 (0)