Skip to content

Commit eca11f7

Browse files
authored
Document code analysis rules CA1873, CA1874, CA1875, CA2023 (#49492)
1 parent fc53a3a commit eca11f7

File tree

8 files changed

+639
-43
lines changed

8 files changed

+639
-43
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
title: "CA1873: Avoid potentially expensive logging (code analysis)"
3+
description: "Learn about code analysis rule CA1873: Avoid potentially expensive logging"
4+
ms.date: 10/27/2025
5+
ms.topic: reference
6+
f1_keywords:
7+
- CA1873
8+
- AvoidPotentiallyExpensiveCallWhenLoggingAnalyzer
9+
helpviewer_keywords:
10+
- CA1873
11+
dev_langs:
12+
- CSharp
13+
- VB
14+
ai-usage: ai-generated
15+
---
16+
17+
# CA1873: Avoid potentially expensive logging
18+
19+
| Property | Value |
20+
|-------------------------------------|----------------------------------------|
21+
| **Rule ID** | CA1873 |
22+
| **Title** | Avoid potentially expensive logging |
23+
| **Category** | [Performance](performance-warnings.md) |
24+
| **Fix is breaking or non-breaking** | Non-breaking |
25+
| **Enabled by default in .NET 10** | As suggestion |
26+
27+
## Cause
28+
29+
In many situations, logging is disabled or set to a log level that results in an unnecessary evaluation for logging arguments.
30+
31+
## Rule description
32+
33+
When logging methods are called, their arguments are evaluated regardless of whether the logging level is enabled. This can result in expensive operations being executed even when the log message won't be written. For better performance, guard expensive logging calls with a check to <xref:Microsoft.Extensions.Logging.ILogger.IsEnabled%2A> or use the `LoggerMessage` pattern.
34+
35+
## How to fix violations
36+
37+
To fix a violation of this rule, use one of the following approaches:
38+
39+
- Guard the logging call with a check to <xref:Microsoft.Extensions.Logging.ILogger.IsEnabled%2A>.
40+
- Use the `LoggerMessage` pattern with <xref:Microsoft.Extensions.Logging.LoggerMessageAttribute>.
41+
- Ensure expensive operations aren't performed in logging arguments unless necessary.
42+
43+
## Example
44+
45+
The following code snippet shows violations of CA1873:
46+
47+
```csharp
48+
using Microsoft.Extensions.Logging;
49+
50+
class Example
51+
{
52+
private readonly ILogger _logger;
53+
54+
public Example(ILogger<Example> logger)
55+
{
56+
_logger = logger;
57+
}
58+
59+
public void ProcessData(int[] data)
60+
{
61+
// Violation: expensive operation in logging argument.
62+
_logger.LogDebug($"Processing {string.Join(", ", data)} items");
63+
64+
// Violation: object creation in logging argument.
65+
_logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data });
66+
}
67+
}
68+
```
69+
70+
```vb
71+
Imports Microsoft.Extensions.Logging
72+
73+
Class Example
74+
Private ReadOnly _logger As ILogger
75+
76+
Public Sub New(logger As ILogger(Of Example))
77+
_logger = logger
78+
End Sub
79+
80+
Public Sub ProcessData(data As Integer())
81+
' Violation: expensive operation in logging argument.
82+
_logger.LogDebug($"Processing {String.Join(", ", data)} items")
83+
84+
' Violation: object creation in logging argument.
85+
_logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data})
86+
End Sub
87+
End Class
88+
```
89+
90+
The following code snippet fixes the violations:
91+
92+
```csharp
93+
using Microsoft.Extensions.Logging;
94+
95+
class Example
96+
{
97+
private readonly ILogger _logger;
98+
99+
public Example(ILogger<Example> logger)
100+
{
101+
_logger = logger;
102+
}
103+
104+
public void ProcessData(int[] data)
105+
{
106+
// Fixed: guard with IsEnabled check.
107+
if (_logger.IsEnabled(LogLevel.Debug))
108+
{
109+
_logger.LogDebug($"Processing {string.Join(", ", data)} items");
110+
}
111+
112+
// Fixed: guard with IsEnabled check.
113+
if (_logger.IsEnabled(LogLevel.Trace))
114+
{
115+
_logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data });
116+
}
117+
}
118+
}
119+
```
120+
121+
```vb
122+
Imports Microsoft.Extensions.Logging
123+
124+
Class Example
125+
Private ReadOnly _logger As ILogger
126+
127+
Public Sub New(logger As ILogger(Of Example))
128+
_logger = logger
129+
End Sub
130+
131+
Public Sub ProcessData(data As Integer())
132+
' Fixed: guard with IsEnabled check.
133+
If _logger.IsEnabled(LogLevel.Debug) Then
134+
_logger.LogDebug($"Processing {String.Join(", ", data)} items")
135+
End If
136+
137+
' Fixed: guard with IsEnabled check.
138+
If _logger.IsEnabled(LogLevel.Trace) Then
139+
_logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data})
140+
End If
141+
End Sub
142+
End Class
143+
```
144+
145+
## When to suppress warnings
146+
147+
It's safe to suppress a warning from this rule if performance isn't a concern or if the logging arguments don't involve expensive operations.
148+
149+
## Suppress a warning
150+
151+
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
152+
153+
```csharp
154+
#pragma warning disable CA1873
155+
// The code that's violating the rule is on this line.
156+
#pragma warning restore CA1873
157+
```
158+
159+
To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md).
160+
161+
```ini
162+
[*.{cs,vb}]
163+
dotnet_diagnostic.CA1873.severity = none
164+
```
165+
166+
For more information, see [How to suppress code analysis warnings](../suppress-warnings.md).
167+
168+
## See also
169+
170+
- [Performance rules](performance-warnings.md)
171+
- [High-performance logging in .NET](../../../core/extensions/high-performance-logging.md)
172+
- [Compile-time logging source generation](../../../core/extensions/logger-message-generator.md)
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
title: "CA1874: Use 'Regex.IsMatch' (code analysis)"
3+
description: "Learn about code analysis rule CA1874: Use 'Regex.IsMatch'"
4+
ms.date: 10/27/2025
5+
ms.topic: reference
6+
f1_keywords:
7+
- CA1874
8+
- UseRegexIsMatchAnalyzer
9+
helpviewer_keywords:
10+
- CA1874
11+
dev_langs:
12+
- CSharp
13+
- VB
14+
ai-usage: ai-generated
15+
---
16+
17+
# CA1874: Use 'Regex.IsMatch'
18+
19+
| Property | Value |
20+
|-------------------------------------|----------------------------------------|
21+
| **Rule ID** | CA1874 |
22+
| **Title** | Use `Regex.IsMatch` |
23+
| **Category** | [Performance](performance-warnings.md) |
24+
| **Fix is breaking or non-breaking** | Non-breaking |
25+
| **Enabled by default in .NET 10** | As suggestion |
26+
27+
## Cause
28+
29+
The <xref:System.Text.RegularExpressions.Group.Success> property of the result from <xref:System.Text.RegularExpressions.Regex.Match%2A?displayProperty=nameWithType> is used to check if a pattern matches.
30+
31+
## Rule description
32+
33+
<xref:System.Text.RegularExpressions.Regex.IsMatch*?displayProperty=nameWithType> is simpler and faster than `Regex.Match(...).Success`. The `IsMatch` method is optimized for the case where you only need to know whether a match exists, rather than what the match is. Calling `Match()` and then checking <xref:System.Text.RegularExpressions.Group.Success> does unnecessary work that can impact performance.
34+
35+
## How to fix violations
36+
37+
Replace calls to `Regex.Match(...).Success` with `Regex.IsMatch(...)`.
38+
39+
A *code fix* that automatically performs this transformation is available.
40+
41+
## Example
42+
43+
The following code snippet shows a violation of CA1874:
44+
45+
```csharp
46+
using System.Text.RegularExpressions;
47+
48+
class Example
49+
{
50+
public bool IsValidEmail(string email)
51+
{
52+
// Violation
53+
return Regex.Match(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$").Success;
54+
}
55+
}
56+
```
57+
58+
```vb
59+
Imports System.Text.RegularExpressions
60+
61+
Class Example
62+
Public Function IsValidEmail(email As String) As Boolean
63+
' Violation
64+
Return Regex.Match(email, "^[^@\s]+@[^@\s]+\.[^@\s]+$").Success
65+
End Function
66+
End Class
67+
```
68+
69+
The following code snippet fixes the violation:
70+
71+
```csharp
72+
using System.Text.RegularExpressions;
73+
74+
class Example
75+
{
76+
public bool IsValidEmail(string email)
77+
{
78+
// Fixed
79+
return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$");
80+
}
81+
}
82+
```
83+
84+
```vb
85+
Imports System.Text.RegularExpressions
86+
87+
Class Example
88+
Public Function IsValidEmail(email As String) As Boolean
89+
' Fixed
90+
Return Regex.IsMatch(email, "^[^@\s]+@[^@\s]+\.[^@\s]+$")
91+
End Function
92+
End Class
93+
```
94+
95+
## When to suppress warnings
96+
97+
It's safe to suppress a warning from this rule if performance isn't a concern.
98+
99+
## Suppress a warning
100+
101+
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
102+
103+
```csharp
104+
#pragma warning disable CA1874
105+
// The code that's violating the rule is on this line.
106+
#pragma warning restore CA1874
107+
```
108+
109+
To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md).
110+
111+
```ini
112+
[*.{cs,vb}]
113+
dotnet_diagnostic.CA1874.severity = none
114+
```
115+
116+
For more information, see [How to suppress code analysis warnings](../suppress-warnings.md).
117+
118+
## See also
119+
120+
- [Performance rules](performance-warnings.md)
121+
- <xref:System.Text.RegularExpressions.Regex.IsMatch%2A?displayProperty=nameWithType>
122+
- <xref:System.Text.RegularExpressions.Regex.Match%2A?displayProperty=nameWithType>

0 commit comments

Comments
 (0)