From 771a9c95da00d0cf143b26407d495e2d05b0c78e Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Tue, 28 Oct 2025 08:15:36 -0700 Subject: [PATCH 1/7] Update breaking change issue template for .NET versions (#49501) Removed .NET 10 Preview versions and added .NET 11 Preview versions in the breaking change issue template. --- .github/ISSUE_TEMPLATE/02-breaking-change.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/02-breaking-change.yml b/.github/ISSUE_TEMPLATE/02-breaking-change.yml index f7b99d7f3cb05..bf65a73095d61 100644 --- a/.github/ISSUE_TEMPLATE/02-breaking-change.yml +++ b/.github/ISSUE_TEMPLATE/02-breaking-change.yml @@ -23,15 +23,14 @@ body: options: - .NET 8 - .NET 9 - - .NET 10 Preview 4 - - .NET 10 Preview 5 - - .NET 10 Preview 6 - - .NET 10 Preview 7 - .NET 10 RC 1 - .NET 10 RC 2 - .NET 10 GA - .NET 11 Preview 1 - - .NEt 11 Preview 2 + - .NET 11 Preview 2 + - .NET 11 Preview 3 + - .NET 11 Preview 4 + - .NET 11 Preview 5 - Other (please put exact version in description textbox) validations: required: true From 1107d47bae609933a00050635a39d4c8c06e6264 Mon Sep 17 00:00:00 2001 From: mariamgerges Date: Tue, 28 Oct 2025 17:29:28 +0100 Subject: [PATCH 2/7] Adding docs for Application metadata and application enricher (#49395) * adding docs * fixes * fixing warning * fixed reference * fixes * fixes * fixes * missing new line * missing tick * fix * fix * fixing code blokcs * comments * fix sample --- .../enrichment/application-log-enricher.md | 141 +++++++++++ docs/core/enrichment/application-metadata.md | 239 ++++++++++++++++++ .../snippets/servicelogenricher/Program.cs | 23 ++ .../servicelogenricher/appsettings.json | 12 + .../servicelogenricher/output-full.json | 14 + .../servicelogenricher.csproj | 24 ++ docs/navigate/tools-diagnostics/toc.yml | 4 + 7 files changed, 457 insertions(+) create mode 100644 docs/core/enrichment/application-log-enricher.md create mode 100644 docs/core/enrichment/application-metadata.md create mode 100644 docs/core/enrichment/snippets/servicelogenricher/Program.cs create mode 100644 docs/core/enrichment/snippets/servicelogenricher/appsettings.json create mode 100644 docs/core/enrichment/snippets/servicelogenricher/output-full.json create mode 100644 docs/core/enrichment/snippets/servicelogenricher/servicelogenricher.csproj diff --git a/docs/core/enrichment/application-log-enricher.md b/docs/core/enrichment/application-log-enricher.md new file mode 100644 index 0000000000000..2bf801420aecf --- /dev/null +++ b/docs/core/enrichment/application-log-enricher.md @@ -0,0 +1,141 @@ +--- +title: Application log enricher +description: Learn how to use the application log enricher to add application-specific information to your telemetry in .NET. +ms.date: 10/14/2025 +--- + +# Application log enricher + +The application log enricher augments telemetry logs with application-specific information such as service host details and application metadata. This enricher provides essential context about your application's deployment environment, version information, and service identity that helps with monitoring, debugging, and operational visibility. + +You can register the enrichers in an IoC container, and all registered enrichers are automatically picked up by respective telemetry logs, where they enrich the telemetry information. + +## Prerequisites + +To function properly, this enricher requires that [application metadata](application-metadata.md) is configured and available. The application metadata provides the foundational information that the enricher uses to populate telemetry dimensions. + +## Install the package + +To get started, install the [📦 Microsoft.Extensions.Telemetry](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry) NuGet package: + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Microsoft.Extensions.Telemetry +``` + +Or, if you're using .NET 10+ SDK: + +```dotnetcli +dotnet package add Microsoft.Extensions.Telemetry +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +## Application log enricher + +The application log enricher provides application-specific enrichment. The log enricher specifically targets log telemetry and adds standardized dimensions that help identify and categorize log entries by service characteristics. + +### Step-by-step configuration + +Follow these steps to configure the application log enricher in your application: + +#### 1. Configure Application Metadata + +First, configure the [Application Metadata](application-metadata.md) by calling the methods: + +```csharp +var builder = Host.CreateApplicationBuilder(args); +builder.UseApplicationMetadata() +``` + +This method automatically picks up values from the and saves them to the default configuration section `ambientmetadata:application`. + +Alternatively, you can use this method , which registers a configuration provider for application metadata by picking up the values from the and adds it to the given configuration section name. Then you use method to register the metadata in the dependency injection container, which allow you to pass separately: + +```csharp +var builder = Host.CreateApplicationBuilder(args) + .ConfigureAppConfiguration(static (context, builder) => + builder.AddApplicationMetadata(context.HostingEnvironment)); + +builder.Services.AddApplicationMetadata( + builder.Configuration.GetSection("ambientmetadata:application"))); +``` + +#### 2. Provide additional configuration (optional) + +You can provide additional configuration via `appsettings.json`. There are two properties in the [Application Metadata](application-metadata.md) that don't get values automatically: `BuildVersion` and `DeploymentRing`. If you want to use them, provide values manually: + +:::code language="json" source="snippets/servicelogenricher/appsettings.json" range="2-7"::: + +#### 3. Register the service log enricher + +Register the log enricher into the dependency injection container using : + +```csharp +serviceCollection.AddServiceLogEnricher(); +``` + +You can enable or disable individual options of the enricher using : + +```csharp +serviceCollection.AddServiceLogEnricher(options => +{ + options.BuildVersion = true; + options.DeploymentRing = true; +}); +``` + +Alternatively, configure options using `appsettings.json`: + +:::code language="json" source="snippets/servicelogenricher/appsettings.json" range="8-11"::: + +And apply the configuration using : + +```csharp +var builder = Host.CreateApplicationBuilder(args); +builder.Services.AddServiceLogEnricher(builder.Configuration.GetSection("ApplicationLogEnricherOptions")); + +``` + +### `ApplicationLogEnricherOptions` Configuration options + +The service log enricher supports several configuration options through the class: + +| Property | Default Value | Dimension Name | Description | +|----------|---------------|----------------|-------------| +| `EnvironmentName` | true | `deployment.environment` | Environment name from hosting environment or configuration | +| `ApplicationName` | true | `service.name` | Application name from hosting environment or configuration | +| `BuildVersion` | false | `service.version` | Build version from configuration | +| `DeploymentRing` | false | `DeploymentRing` | Deployment ring from configuration | + +By default, the enricher includes `EnvironmentName` and `ApplicationName` in log entries. The `BuildVersion` and `DeploymentRing` properties are disabled by default and must be explicitly enabled if needed. + +### Complete example + +Here's a complete example showing how to set up the service log enricher: + +**appsettings.json:** + +:::code language="json" source="snippets/servicelogenricher/appsettings.json"::: + +**Program.cs:** + +:::code language="csharp" source="snippets/servicelogenricher/Program.cs" ::: + +### Enriched log output + +With the service log enricher configured, your log output will include service-specific dimensions: + +:::code language="json" source="snippets/servicelogenricher/output-full.json" highlight="8-11" ::: + +## Next steps + +- Learn about [application metadata configuration](application-metadata.md) diff --git a/docs/core/enrichment/application-metadata.md b/docs/core/enrichment/application-metadata.md new file mode 100644 index 0000000000000..08e6dcfad3a3c --- /dev/null +++ b/docs/core/enrichment/application-metadata.md @@ -0,0 +1,239 @@ +--- +title: Application metadata +description: Learn how to use the application metadata to add service-specific information to your service in .NET. +ms.date: 10/14/2025 +--- + +# Application ambient metadata + +The [`Microsoft.Extensions.AmbientMetadata.Application`](https://www.nuget.org/packages/Microsoft.Extensions.AmbientMetadata.Application) NuGet package provides functionality to capture and flow application-level ambient metadata throughout your application. This metadata includes information such as the application name, version, deployment environment, and deployment ring, which is valuable for enriching telemetry, troubleshooting, and analysis. + +## Why use application metadata + +Application metadata provides essential context about your running application that can enhance observability: + +- **Telemetry enrichment**: Automatically add application details to logs, metrics, and traces. +- **Troubleshooting**: Quickly identify which version of your application is experiencing issues. +- **Environment identification**: Distinguish between different environments in your telemetry. +- **Deployment tracking**: Track issues across different deployment rings or regions. +- **Consistent metadata**: Ensure all components in your application use the same metadata values. + +## Install the package + +To get started, install the [📦 Microsoft.Extensions.AmbientMetadata.Application](https://www.nuget.org/packages/Microsoft.Extensions.AmbientMetadata.Application) NuGet package: + +### [.NET CLI](#tab/dotnet-cli) + +```dotnetcli +dotnet add package Microsoft.Extensions.AmbientMetadata.Application +``` + +Or, if you're using .NET 10+ SDK: + +```dotnetcli +dotnet package add Microsoft.Extensions.AmbientMetadata.Application +``` + +### [PackageReference](#tab/package-reference) + +```xml + +``` + +--- + +## Configure application metadata + +Application metadata can be configured through your application's configuration system. The package looks for metadata under the `ambientmetadata:application` configuration section by default. + +### Configure with appsettings.json + +Add the application metadata to your `appsettings.json` file: + +```json +{ + "ambientmetadata": { + "application": { + "ApplicationName": "MyWebApi", + "BuildVersion": "1.0.0", + "DeploymentRing": "Production", + "EnvironmentName": "Production" + } + } +} +``` + +### Configure with IHostBuilder + +Use the extensions method to register application metadata, which populates `ApplicationName` and `EnvironmentName` values automatically from `IHostEnvironment`. +Optionally, you can provide values for `BuildVersion` and `DeploymentRing` via the `appsettings.json` file. + +The following table shows the metadata made available by the provider via : + +| Key | Required? | Where the value comes from| Value Example | Description| +|-|-|-|-|-| +| `ambientmetadata:application:applicationname` | yes | automatically from `IHostEnvironment` |`myApp` | The application name.| +| `ambientmetadata:application:environmentname` | yes | automatically from `IHostEnvironment` | `Production`, `Development`| The environment the application is deployed to.| +| `ambientmetadata:application:buildversion` | no | configure it in `IConfiguration` | `1.0.0-rc1` | The application's build version.| +| `ambientmetadata:application:deploymentring` | no | configure it in `IConfiguration` | `r0`, `public` | The deployment ring from where the application is running.| + +```csharp +var builder = Host.CreateDefaultBuilder(args) + // ApplicationName and EnvironmentName will be imported from `IHostEnvironment` + // BuildVersion and DeploymentRing will be imported from the "appsettings.json" file. +builder.UseApplicationMetadata(); + +var host = builder.Build(); +await host.StartAsync(); + +var metadataOptions = host.Services.GetRequiredService>(); +var buildVersion = metadataOptions.Value.BuildVersion; +``` + +Alternatively, you can achieve the same result as above by doing this: + +```csharp +var builder = Host.CreateApplicationBuilder() + .ConfigureAppConfiguration(static (context, builder) => + builder.AddApplicationMetadata(context.HostingEnvironment)); +builder.Services.AddApplicationMetadata( + builder.Configuration.GetSection("ambientmetadata:application"))); +var host = builder.Build(); + +var metadataOptions = host.Services.GetRequiredService>(); +var buildVersion = metadataOptions.Value.BuildVersion; +``` + +Your `appsettings.json` can have a section as follows : + +:::code language="json" source="snippets/servicelogenricher/appsettings.json" range="2-7"::: + +### Configure with IHostApplicationBuilder + +For applications using : + +```csharp +var builder = Host.CreateApplicationBuilder(args) + // ApplicationName and EnvironmentName will be imported from `IHostEnvironment` + // BuildVersion and DeploymentRing will be imported from the "appsettings.json" file. +builder.UseApplicationMetadata(); + +var host = builder.Build(); +await host.StartAsync(); + +var metadataOptions = host.Services.GetRequiredService>(); +var buildVersion = metadataOptions.Value.BuildVersion; +``` + +Your `appsettings.json` can have a section as follows : + +:::code language="json" source="snippets/servicelogenricher/appsettings.json" range="2-7"::: + +## Access application metadata + +Once configured, you can inject and use the type: + +```csharp +using Microsoft.Extensions.AmbientMetadata; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; + +var builder = Host.CreateApplicationBuilder(args); +builder.UseApplicationMetadata(); + +var host = builder.Build(); + +var metadata = host.Services.GetRequiredService>().Value; +Console.WriteLine($"Application: {metadata.ApplicationName}"); +Console.WriteLine($"Version: {metadata.BuildVersion}"); +Console.WriteLine($"Environment: {metadata.EnvironmentName}"); +Console.WriteLine($"Deployment Ring: {metadata.DeploymentRing}"); +await host.RunAsync(); +``` + +## ApplicationMetadata properties + +The class includes the following properties: + +| Property | Description | +|----------|-------------| +| `ApplicationName` | The name of the application. | +| `BuildVersion` | The version of the application build. | +| `DeploymentRing` | The deployment ring or stage (for example, Canary, Production). | +| `EnvironmentName` | The environment where the application is running (for example, Development, Staging, Production). | + +## Use with logging + +Application metadata is particularly useful for enriching log messages: + +```csharp +using Microsoft.Extensions.AmbientMetadata; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +var builder = Host.CreateApplicationBuilder(args); + +builder.UseApplicationMetadata(); +builder.Services.AddSingleton(); + +var host = builder.Build(); + +var loggingService = host.Services.GetRequiredService(); +loggingService.LogWithMetadata(); + +await host.RunAsync(); + +public class LoggingService( + ILogger logger, + IOptions metadata) +{ + private readonly ILogger _logger = logger; + private readonly ApplicationMetadata _metadata = metadata.Value; + + public void LogWithMetadata() + { + _logger.LogInformation( + "Processing request in {ApplicationName} v{Version} ({Environment})", + _metadata.ApplicationName, + _metadata.BuildVersion, + _metadata.EnvironmentName); + } +} +``` + +## Custom configuration section + +If you prefer to use a different configuration section name, specify it when calling : + +```csharp +using Microsoft.Extensions.Hosting; + +var builder = Host.CreateApplicationBuilder(args); + +// Use custom configuration section +builder.UseApplicationMetadata("myapp:metadata"); + +var host = builder.Build(); + +await host.RunAsync(); +``` + +With this configuration, your settings would look like: + +```json +{ + "myapp": { + "metadata": { + "ApplicationName": "MyWebApi", // Your ApplicationName will be imported from `IHostEnvironment` + "BuildVersion": "1.0.0", + "DeploymentRing": "Production", + "EnvironmentName": "Production" // Your EnvironmentName will be imported from `IHostEnvironment` + } + } +} +``` diff --git a/docs/core/enrichment/snippets/servicelogenricher/Program.cs b/docs/core/enrichment/snippets/servicelogenricher/Program.cs new file mode 100644 index 0000000000000..9c7b7d03e929b --- /dev/null +++ b/docs/core/enrichment/snippets/servicelogenricher/Program.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +var builder = Host.CreateApplicationBuilder(args); +builder.UseApplicationMetadata(); +builder.Logging.EnableEnrichment(); +builder.Logging.AddJsonConsole(op => +{ + op.JsonWriterOptions = new JsonWriterOptions + { + Indented = true + }; +}); +builder.Services.AddServiceLogEnricher(builder.Configuration.GetSection("ApplicationLogEnricherOptions")); + +var host = builder.Build(); +var logger = host.Services.GetRequiredService>(); + +logger.LogInformation("This is a sample log message"); + +await host.RunAsync(); diff --git a/docs/core/enrichment/snippets/servicelogenricher/appsettings.json b/docs/core/enrichment/snippets/servicelogenricher/appsettings.json new file mode 100644 index 0000000000000..263f4b20b705c --- /dev/null +++ b/docs/core/enrichment/snippets/servicelogenricher/appsettings.json @@ -0,0 +1,12 @@ +{ + "AmbientMetadata": { + "Application": { + "DeploymentRing": "testring", + "BuildVersion": "1.2.3" + } + }, + "ApplicationLogEnricherOptions": { + "BuildVersion": true, + "DeploymentRing": true + } +} diff --git a/docs/core/enrichment/snippets/servicelogenricher/output-full.json b/docs/core/enrichment/snippets/servicelogenricher/output-full.json new file mode 100644 index 0000000000000..422cb4c0489db --- /dev/null +++ b/docs/core/enrichment/snippets/servicelogenricher/output-full.json @@ -0,0 +1,14 @@ +{ + "EventId": 0, + "LogLevel": "Information", + "Category": "Program", + "Message": "This is a sample log message", + "State": { + "Message": "This is a sample log message", + "service.name": "servicelogenricher", + "deployment.environment": "Production", + "DeploymentRing": "testring", + "service.version": "1.2.3", + "{OriginalFormat}": "This is a sample log message" + } +} \ No newline at end of file diff --git a/docs/core/enrichment/snippets/servicelogenricher/servicelogenricher.csproj b/docs/core/enrichment/snippets/servicelogenricher/servicelogenricher.csproj new file mode 100644 index 0000000000000..714f32824ed44 --- /dev/null +++ b/docs/core/enrichment/snippets/servicelogenricher/servicelogenricher.csproj @@ -0,0 +1,24 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/docs/navigate/tools-diagnostics/toc.yml b/docs/navigate/tools-diagnostics/toc.yml index 6074077eebbdf..c9a3ddc0e8082 100644 --- a/docs/navigate/tools-diagnostics/toc.yml +++ b/docs/navigate/tools-diagnostics/toc.yml @@ -450,6 +450,10 @@ items: items: - name: Overview href: ../../core/enrichment/overview.md + - name: Application metadata + href: ../../core/enrichment/application-metadata.md + - name: Application log enricher + href: ../../core/enrichment/application-log-enricher.md - name: Process log enricher href: ../../core/enrichment/process-log-enricher.md - name: Custom enricher From d0e1196a9da724b6d3b2352052d6d457ff6b5596 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Tue, 28 Oct 2025 10:51:42 -0700 Subject: [PATCH 3/7] Remove redundant line about metric method constraints (#49502) --- docs/core/diagnostics/metrics-generator.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/core/diagnostics/metrics-generator.md b/docs/core/diagnostics/metrics-generator.md index 580499d5de661..ff80bea2499f1 100644 --- a/docs/core/diagnostics/metrics-generator.md +++ b/docs/core/diagnostics/metrics-generator.md @@ -87,7 +87,6 @@ Metric methods are constrained to the following: - Their names must not start with an underscore. - Their parameter names must not start with an underscore. - Their first parameter must be type. -Metric methods are constrained to the following: ## See also From 6b44590e8c4f8074eca33fd725553e13105633f5 Mon Sep 17 00:00:00 2001 From: Alexander Gayko Date: Tue, 28 Oct 2025 19:12:41 +0100 Subject: [PATCH 4/7] Fix ProjectReference path in preprocessor directives (#49507) those two samples should refer to the same --- docs/csharp/language-reference/preprocessor-directives.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/csharp/language-reference/preprocessor-directives.md b/docs/csharp/language-reference/preprocessor-directives.md index 6d6f0625fee15..0634dea29a2df 100644 --- a/docs/csharp/language-reference/preprocessor-directives.md +++ b/docs/csharp/language-reference/preprocessor-directives.md @@ -121,7 +121,7 @@ The `#:` directives that are used in file-based apps include: The preceding preprocessor token is translated into: ```xml - + ``` Tools can add new tokens following the `#:` convention. From 4d12ca02369aecdc77ec060f551f72ea15fa91d5 Mon Sep 17 00:00:00 2001 From: Tara Overfield Date: Tue, 28 Oct 2025 11:49:29 -0700 Subject: [PATCH 5/7] October Preview Update (#49506) * October Preview Update * Update docs/framework/release-notes/release-notes.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> * Update 10-28-october-cumulative-update-preview.md * Revise October 2025 cumulative update to preview Updated the release notes to reflect the preview status and new release date. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- ...10-28-october-cumulative-update-preview.md | 38 +++++++++++++++++++ docs/framework/release-notes/release-notes.md | 5 ++- docs/framework/toc.yml | 2 + 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md diff --git a/docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md b/docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md new file mode 100644 index 0000000000000..3f3b38c530813 --- /dev/null +++ b/docs/framework/release-notes/2025/10-28-october-cumulative-update-preview.md @@ -0,0 +1,38 @@ +--- +title: October 2025 cumulative update preview +description: Learn about the improvements in the .NET Framework October 2025 cumulative update preview. +ms.date: 10/28/2025 +--- +# October 2025 cumulative update preview + +_Released October 28, 2025_ + +## Summary of what's new in this release + +- [Security improvements](#security-improvements) +- [Quality and reliability improvements](#quality-and-reliability-improvements) + +### Security improvements + +There are no new security improvements in this release. This update is cumulative and contains all previously released security improvements. + +### Quality and reliability improvements + +#### .NET Runtime + +Addresses an issue to update operating systeam calls for compliance with current standards. (*Applies to: .NET Framework 4.8.1*) + +## Known issues in this release + +This release contains no known issues. + +## Summary tables + +The following table outlines the updates in this release. + +| Product version | Cumulative update preview | +| --- | --- | +| **Windows 11, version 25H2** | | +| .NET Framework 3.5, 4.8.1 | [5067931](https://support.microsoft.com/kb/5067931) | + +The operating system row lists a KB that's used for update offering purposes. When the operating system KB is offered, the applicability logic determines the specific .NET Framework update(s) installed. Updates for individual .NET Framework versions are installed based on the version of .NET Framework that is already present on the device. Because of this, the operating system KB is not expected to be listed as installed updates on the device. The expected updates installed are the .NET Framework-specific version updates listed in the previous table. diff --git a/docs/framework/release-notes/release-notes.md b/docs/framework/release-notes/release-notes.md index 6491d8c404554..423bda683ab52 100644 --- a/docs/framework/release-notes/release-notes.md +++ b/docs/framework/release-notes/release-notes.md @@ -11,8 +11,9 @@ The .NET Framework updates include cumulative security and reliability improveme .NET Framework cumulative update releases are discussed in detail in the following individual release notes: -* October 14, 2025 - [cumulative update preview](./2025/10-14-october-cumulative-update.md) **New Release** -* September 9, 2025 - [cumulative update preview](./2025/09-09-september-cumulative-update.md) +* October 28, 2025 - [cumulative update preview](./2025/10-28-october-cumulative-update-preview.md) **New Release** +* October 14, 2025 - [cumulative update](./2025/10-14-october-cumulative-update.md) +* September 9, 2025 - [cumulative update](./2025/09-09-september-cumulative-update.md) * August 26, 2025 - [cumulative update preview](./2025/08-26-august-cumulative-update-preview.md) * July 8, 2025 - [cumulative update](./2025/07-08-july-cumulative-update.md) * April 22, 2025 - [cumulative update preview](./2025/04-22-april-cumulative-update-preview.md) diff --git a/docs/framework/toc.yml b/docs/framework/toc.yml index a41f7ee6ac290..2212028c2615c 100644 --- a/docs/framework/toc.yml +++ b/docs/framework/toc.yml @@ -705,6 +705,8 @@ items: href: release-notes/2025/09-09-september-cumulative-update.md - name: October 2025 cumulative update href: release-notes/2025/10-14-october-cumulative-update.md + - name: October 2025 cumulative update preview + href: release-notes/2025/10-28-october-cumulative-update-preview.md - name: What's new href: whats-new/index.md - name: What's new in accessibility From fc53a3acd45fd02f3ec0cc56aea99a9f0d212887 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Tue, 28 Oct 2025 21:43:21 +0000 Subject: [PATCH 6/7] Fix RegexOptions.ECMAScript combinations (#49453) `ECMAScript` can be used in conjunction with `Compiled` according to https://learn.microsoft.com/dotnet/api/system.text.regularexpressions.regexoptions --- docs/standard/base-types/regular-expression-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/base-types/regular-expression-options.md b/docs/standard/base-types/regular-expression-options.md index 555e1e13515fa..911d9ca8a6c87 100644 --- a/docs/standard/base-types/regular-expression-options.md +++ b/docs/standard/base-types/regular-expression-options.md @@ -333,7 +333,7 @@ By default, the regular expression engine uses canonical behavior when matching > [!NOTE] > ECMAScript-compliant behavior is available only by supplying the value to the `options` parameter of a class constructor or static pattern-matching method. It is not available as an inline option. -The option can be combined only with the and options. The use of any other option in a regular expression results in an . +The option can be combined only with the , , and options. The use of any other option in a regular expression results in an . The behavior of ECMAScript and canonical regular expressions differs in three areas: character class syntax, self-referencing capturing groups, and octal versus backreference interpretation. From eca11f7c35e934da5b33805f20930046b885d07b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:37:40 -0700 Subject: [PATCH 7/7] Document code analysis rules CA1873, CA1874, CA1875, CA2023 (#49492) --- .../code-analysis/quality-rules/ca1873.md | 172 ++++++++++++++++++ .../code-analysis/quality-rules/ca1874.md | 122 +++++++++++++ .../code-analysis/quality-rules/ca1875.md | 122 +++++++++++++ .../code-analysis/quality-rules/ca2023.md | 166 +++++++++++++++++ .../code-analysis/quality-rules/index.md | 76 ++++---- .../quality-rules/performance-warnings.md | 7 +- .../quality-rules/reliability-warnings.md | 9 +- docs/navigate/tools-diagnostics/toc.yml | 8 + 8 files changed, 639 insertions(+), 43 deletions(-) create mode 100644 docs/fundamentals/code-analysis/quality-rules/ca1873.md create mode 100644 docs/fundamentals/code-analysis/quality-rules/ca1874.md create mode 100644 docs/fundamentals/code-analysis/quality-rules/ca1875.md create mode 100644 docs/fundamentals/code-analysis/quality-rules/ca2023.md diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1873.md b/docs/fundamentals/code-analysis/quality-rules/ca1873.md new file mode 100644 index 0000000000000..3124289584046 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/ca1873.md @@ -0,0 +1,172 @@ +--- +title: "CA1873: Avoid potentially expensive logging (code analysis)" +description: "Learn about code analysis rule CA1873: Avoid potentially expensive logging" +ms.date: 10/27/2025 +ms.topic: reference +f1_keywords: + - CA1873 + - AvoidPotentiallyExpensiveCallWhenLoggingAnalyzer +helpviewer_keywords: + - CA1873 +dev_langs: + - CSharp + - VB +ai-usage: ai-generated +--- + +# CA1873: Avoid potentially expensive logging + +| Property | Value | +|-------------------------------------|----------------------------------------| +| **Rule ID** | CA1873 | +| **Title** | Avoid potentially expensive logging | +| **Category** | [Performance](performance-warnings.md) | +| **Fix is breaking or non-breaking** | Non-breaking | +| **Enabled by default in .NET 10** | As suggestion | + +## Cause + +In many situations, logging is disabled or set to a log level that results in an unnecessary evaluation for logging arguments. + +## Rule description + +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 or use the `LoggerMessage` pattern. + +## How to fix violations + +To fix a violation of this rule, use one of the following approaches: + +- Guard the logging call with a check to . +- Use the `LoggerMessage` pattern with . +- Ensure expensive operations aren't performed in logging arguments unless necessary. + +## Example + +The following code snippet shows violations of CA1873: + +```csharp +using Microsoft.Extensions.Logging; + +class Example +{ + private readonly ILogger _logger; + + public Example(ILogger logger) + { + _logger = logger; + } + + public void ProcessData(int[] data) + { + // Violation: expensive operation in logging argument. + _logger.LogDebug($"Processing {string.Join(", ", data)} items"); + + // Violation: object creation in logging argument. + _logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data }); + } +} +``` + +```vb +Imports Microsoft.Extensions.Logging + +Class Example + Private ReadOnly _logger As ILogger + + Public Sub New(logger As ILogger(Of Example)) + _logger = logger + End Sub + + Public Sub ProcessData(data As Integer()) + ' Violation: expensive operation in logging argument. + _logger.LogDebug($"Processing {String.Join(", ", data)} items") + + ' Violation: object creation in logging argument. + _logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data}) + End Sub +End Class +``` + +The following code snippet fixes the violations: + +```csharp +using Microsoft.Extensions.Logging; + +class Example +{ + private readonly ILogger _logger; + + public Example(ILogger logger) + { + _logger = logger; + } + + public void ProcessData(int[] data) + { + // Fixed: guard with IsEnabled check. + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug($"Processing {string.Join(", ", data)} items"); + } + + // Fixed: guard with IsEnabled check. + if (_logger.IsEnabled(LogLevel.Trace)) + { + _logger.LogTrace("Data: {Data}", new { Count = data.Length, Items = data }); + } + } +} +``` + +```vb +Imports Microsoft.Extensions.Logging + +Class Example + Private ReadOnly _logger As ILogger + + Public Sub New(logger As ILogger(Of Example)) + _logger = logger + End Sub + + Public Sub ProcessData(data As Integer()) + ' Fixed: guard with IsEnabled check. + If _logger.IsEnabled(LogLevel.Debug) Then + _logger.LogDebug($"Processing {String.Join(", ", data)} items") + End If + + ' Fixed: guard with IsEnabled check. + If _logger.IsEnabled(LogLevel.Trace) Then + _logger.LogTrace("Data: {Data}", New With {.Count = data.Length, .Items = data}) + End If + End Sub +End Class +``` + +## When to suppress warnings + +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. + +## Suppress a warning + +If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. + +```csharp +#pragma warning disable CA1873 +// The code that's violating the rule is on this line. +#pragma warning restore CA1873 +``` + +To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md). + +```ini +[*.{cs,vb}] +dotnet_diagnostic.CA1873.severity = none +``` + +For more information, see [How to suppress code analysis warnings](../suppress-warnings.md). + +## See also + +- [Performance rules](performance-warnings.md) +- [High-performance logging in .NET](../../../core/extensions/high-performance-logging.md) +- [Compile-time logging source generation](../../../core/extensions/logger-message-generator.md) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1874.md b/docs/fundamentals/code-analysis/quality-rules/ca1874.md new file mode 100644 index 0000000000000..263a0c1c01ffc --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/ca1874.md @@ -0,0 +1,122 @@ +--- +title: "CA1874: Use 'Regex.IsMatch' (code analysis)" +description: "Learn about code analysis rule CA1874: Use 'Regex.IsMatch'" +ms.date: 10/27/2025 +ms.topic: reference +f1_keywords: + - CA1874 + - UseRegexIsMatchAnalyzer +helpviewer_keywords: + - CA1874 +dev_langs: + - CSharp + - VB +ai-usage: ai-generated +--- + +# CA1874: Use 'Regex.IsMatch' + +| Property | Value | +|-------------------------------------|----------------------------------------| +| **Rule ID** | CA1874 | +| **Title** | Use `Regex.IsMatch` | +| **Category** | [Performance](performance-warnings.md) | +| **Fix is breaking or non-breaking** | Non-breaking | +| **Enabled by default in .NET 10** | As suggestion | + +## Cause + +The property of the result from is used to check if a pattern matches. + +## Rule description + + 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 does unnecessary work that can impact performance. + +## How to fix violations + +Replace calls to `Regex.Match(...).Success` with `Regex.IsMatch(...)`. + +A *code fix* that automatically performs this transformation is available. + +## Example + +The following code snippet shows a violation of CA1874: + +```csharp +using System.Text.RegularExpressions; + +class Example +{ + public bool IsValidEmail(string email) + { + // Violation + return Regex.Match(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$").Success; + } +} +``` + +```vb +Imports System.Text.RegularExpressions + +Class Example + Public Function IsValidEmail(email As String) As Boolean + ' Violation + Return Regex.Match(email, "^[^@\s]+@[^@\s]+\.[^@\s]+$").Success + End Function +End Class +``` + +The following code snippet fixes the violation: + +```csharp +using System.Text.RegularExpressions; + +class Example +{ + public bool IsValidEmail(string email) + { + // Fixed + return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"); + } +} +``` + +```vb +Imports System.Text.RegularExpressions + +Class Example + Public Function IsValidEmail(email As String) As Boolean + ' Fixed + Return Regex.IsMatch(email, "^[^@\s]+@[^@\s]+\.[^@\s]+$") + End Function +End Class +``` + +## When to suppress warnings + +It's safe to suppress a warning from this rule if performance isn't a concern. + +## Suppress a warning + +If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. + +```csharp +#pragma warning disable CA1874 +// The code that's violating the rule is on this line. +#pragma warning restore CA1874 +``` + +To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md). + +```ini +[*.{cs,vb}] +dotnet_diagnostic.CA1874.severity = none +``` + +For more information, see [How to suppress code analysis warnings](../suppress-warnings.md). + +## See also + +- [Performance rules](performance-warnings.md) +- +- diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1875.md b/docs/fundamentals/code-analysis/quality-rules/ca1875.md new file mode 100644 index 0000000000000..6d3aa8f30b30e --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/ca1875.md @@ -0,0 +1,122 @@ +--- +title: "CA1875: Use 'Regex.Count' (code analysis)" +description: "Learn about code analysis rule CA1875: Use 'Regex.Count'" +ms.date: 10/27/2025 +ms.topic: reference +f1_keywords: + - CA1875 + - UseRegexCountAnalyzer +helpviewer_keywords: + - CA1875 +dev_langs: + - CSharp + - VB +ai-usage: ai-generated +--- + +# CA1875: Use 'Regex.Count' + +| Property | Value | +|-------------------------------------|----------------------------------------| +| **Rule ID** | CA1875 | +| **Title** | Use `Regex.Count` | +| **Category** | [Performance](performance-warnings.md) | +| **Fix is breaking or non-breaking** | Non-breaking | +| **Enabled by default in .NET 10** | As suggestion | + +## Cause + +The property of the `MatchCollection` from is used to get the count of matches. + +## Rule description + + is simpler and faster than `Regex.Matches(...).Count`. The `Count()` method is optimized for counting matches without materializing the full . Calling `Matches()` and then accessing `.Count` does unnecessary work that can impact performance. + +## How to fix violations + +Replace calls to `Regex.Matches(...).Count` with `Regex.Count(...)`. + +A *code fix* that automatically performs this transformation is available. + +## Example + +The following code snippet shows a violation of CA1875: + +```csharp +using System.Text.RegularExpressions; + +class Example +{ + public int CountWords(string text) + { + // Violation + return Regex.Matches(text, @"\b\w+\b").Count; + } +} +``` + +```vb +Imports System.Text.RegularExpressions + +Class Example + Public Function CountWords(text As String) As Integer + ' Violation + Return Regex.Matches(text, "\b\w+\b").Count + End Function +End Class +``` + +The following code snippet fixes the violation: + +```csharp +using System.Text.RegularExpressions; + +class Example +{ + public int CountWords(string text) + { + // Fixed + return Regex.Count(text, @"\b\w+\b"); + } +} +``` + +```vb +Imports System.Text.RegularExpressions + +Class Example + Public Function CountWords(text As String) As Integer + ' Fixed + Return Regex.Count(text, "\b\w+\b") + End Function +End Class +``` + +## When to suppress warnings + +It's safe to suppress a warning from this rule if performance isn't a concern or if you're targeting a version of .NET that doesn't include `Regex.Count` (prior to .NET 7). + +## Suppress a warning + +If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. + +```csharp +#pragma warning disable CA1875 +// The code that's violating the rule is on this line. +#pragma warning restore CA1875 +``` + +To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md). + +```ini +[*.{cs,vb}] +dotnet_diagnostic.CA1875.severity = none +``` + +For more information, see [How to suppress code analysis warnings](../suppress-warnings.md). + +## See also + +- [Performance rules](performance-warnings.md) +- +- diff --git a/docs/fundamentals/code-analysis/quality-rules/ca2023.md b/docs/fundamentals/code-analysis/quality-rules/ca2023.md new file mode 100644 index 0000000000000..6cab8749d689e --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/ca2023.md @@ -0,0 +1,166 @@ +--- +title: "CA2023: Invalid braces in message template (code analysis)" +description: "Learn about code analysis rule CA2023: Invalid braces in message template" +ms.date: 10/27/2025 +ms.topic: reference +f1_keywords: + - CA2023 + - InvalidBracesInMessageTemplateAnalyzer +helpviewer_keywords: + - CA2023 +dev_langs: + - CSharp + - VB +ai-usage: ai-generated +--- + +# CA2023: Invalid braces in message template + +| Property | Value | +|-------------------------------------|------------------------------------------| +| **Rule ID** | CA2023 | +| **Title** | Invalid braces in message template | +| **Category** | [Reliability](reliability-warnings.md) | +| **Fix is breaking or non-breaking** | Non-breaking | +| **Enabled by default in .NET 9** | As warning | + +## Cause + +The braces present in the message template are invalid. Ensure any braces in the message template are valid opening/closing braces, or are escaped. + +## Rule description + +Logging message templates use curly braces `{` and `}` to denote named placeholders for values. Invalid brace usage in message templates can result in runtime exceptions or unexpected logging behavior. This rule detects: + +- Unmatched opening or closing braces. +- Nested braces that aren't properly escaped. +- Other malformed brace patterns. + +## How to fix violations + +To fix a violation of this rule: + +- Ensure all opening braces `{` have a corresponding closing brace `}`. +- Escape literal braces by doubling them: `{{` for `{` and `}}` for `}`. +- Fix any nested or malformed brace patterns. + +## Example + +The following code snippet shows violations of CA2023: + +```csharp +using Microsoft.Extensions.Logging; + +class Example +{ + private readonly ILogger _logger; + + public Example(ILogger logger) + { + _logger = logger; + } + + public void LogData(string name, int value) + { + // Violation: unmatched opening brace. + _logger.LogInformation("Processing {Name with value {Value}", name, value); + + // Violation: unmatched closing brace. + _logger.LogInformation("Processing Name} with value {Value}", name, value); + } +} +``` + +```vb +Imports Microsoft.Extensions.Logging + +Class Example + Private ReadOnly _logger As ILogger + + Public Sub New(logger As ILogger(Of Example)) + _logger = logger + End Sub + + Public Sub LogData(name As String, value As Integer) + ' Violation: unmatched opening brace. + _logger.LogInformation("Processing {Name with value {Value}", name, value) + + ' Violation: unmatched closing brace. + _logger.LogInformation("Processing Name} with value {Value}", name, value) + End Sub +End Class +``` + +The following code snippet fixes the violations: + +```csharp +using Microsoft.Extensions.Logging; + +class Example +{ + private readonly ILogger _logger; + + public Example(ILogger logger) + { + _logger = logger; + } + + public void LogData(string name, int value) + { + // Fixed: proper braces. + _logger.LogInformation("Processing {Name} with value {Value}", name, value); + + // Fixed: escaped literal braces. + _logger.LogInformation("Processing {{Name}} with value {Value}", name, value); + } +} +``` + +```vb +Imports Microsoft.Extensions.Logging + +Class Example + Private ReadOnly _logger As ILogger + + Public Sub New(logger As ILogger(Of Example)) + _logger = logger + End Sub + + Public Sub LogData(name As String, value As Integer) + ' Fixed: proper braces. + _logger.LogInformation("Processing {Name} with value {Value}", name, value) + + ' Fixed: escaped literal braces. + _logger.LogInformation("Processing {{Name}} with value {Value}", name, value) + End Sub +End Class +``` + +## When to suppress warnings + +Don't suppress a warning from this rule. Invalid braces in message templates can cause run-time exceptions or incorrect log output. + +## Suppress a warning + +If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. + +```csharp +#pragma warning disable CA2023 +// The code that's violating the rule is on this line. +#pragma warning restore CA2023 +``` + +To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md). + +```ini +[*.{cs,vb}] +dotnet_diagnostic.CA2023.severity = none +``` + +For more information, see [How to suppress code analysis warnings](../suppress-warnings.md). + +## See also + +- [Reliability rules](reliability-warnings.md) +- [High-performance logging in .NET](../../../core/extensions/high-performance-logging.md) +- [Logging in .NET](../../../core/extensions/logging.md) diff --git a/docs/fundamentals/code-analysis/quality-rules/index.md b/docs/fundamentals/code-analysis/quality-rules/index.md index 009e27c997022..720c1eb06c983 100644 --- a/docs/fundamentals/code-analysis/quality-rules/index.md +++ b/docs/fundamentals/code-analysis/quality-rules/index.md @@ -77,7 +77,7 @@ The following table lists code quality analysis rules. > | [CA1416: Validate platform compatibility](ca1416.md) | Using platform-dependent APIs on a component makes the code no longer work across all platforms. | > | [CA1417: Do not use `OutAttribute` on string parameters for P/Invokes](ca1417.md) | String parameters passed by value with the `OutAttribute` can destabilize the runtime if the string is an interned string. | > | [CA1418: Use valid platform string](ca1418.md) | Platform compatibility analyzer requires a valid platform name and version. | -> | [CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle'](ca1419.md) | Providing a parameterless constructor that is as visible as the containing type for a type derived from `System.Runtime.InteropServices.SafeHandle` enables better performance and usage with source-generated interop solutions. | +> | [CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from `System.Runtime.InteropServices.SafeHandle`](ca1419.md) | Providing a parameterless constructor that is as visible as the containing type for a type derived from `System.Runtime.InteropServices.SafeHandle` enables better performance and usage with source-generated interop solutions. | > | [CA1420: Property, type, or attribute requires runtime marshalling](ca1420.md) | Using features that require runtime marshalling when runtime marshalling is disabled will result in run-time exceptions. | > | [CA1421: Method uses runtime marshalling when DisableRuntimeMarshallingAttribute is applied](ca1421.md) | A method uses runtime marshalling, and runtime marshalling is explicitly disabled. | > | [CA1422: Validate platform compatibility](ca1422.md) | Calling an API that's obsolete in a given OS (version) from a call site that's reachable from that OS (version) is not recommended. | @@ -137,17 +137,17 @@ The following table lists code quality analysis rules. > | [CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array](ca1832.md) | When using a range-indexer on an array and implicitly assigning the value to a or type, the method will be used instead of , which produces a copy of requested portion of the array. | > | [CA1833: Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array](ca1833.md) | When using a range-indexer on an array and implicitly assigning the value to a or type, the method will be used instead of , which produces a copy of requested portion of the array. | > | [CA1834: Use StringBuilder.Append(char) for single character strings](ca1834.md) | has an `Append` overload that takes a `char` as its argument. Prefer calling the `char` overload for performance reasons. | -> | [CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'](ca1835.md) | 'Stream' has a 'ReadAsync' overload that takes a 'Memory<Byte>' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory<Byte>' as the first argument. Prefer calling the memory based overloads, which are more efficient. | +> | [CA1835: Prefer the `Memory`-based overloads for `ReadAsync` and `WriteAsync`](ca1835.md) | `Stream` has a `ReadAsync` overload that takes a `Memory` as the first argument, and a `WriteAsync` overload that takes a `ReadOnlyMemory` as the first argument. Prefer calling the memory based overloads, which are more efficient. | > | [CA1836: Prefer `IsEmpty` over `Count` when available](ca1836.md) | Prefer `IsEmpty` property that is more efficient than `Count`, `Length`, or to determine whether the object contains or not any items. | > | [CA1837: Use `Environment.ProcessId` instead of `Process.GetCurrentProcess().Id`](ca1837.md) | `Environment.ProcessId` is simpler and faster than `Process.GetCurrentProcess().Id`. | -> | [CA1838: Avoid `StringBuilder` parameters for P/Invokes](ca1838.md) | Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. | +> | [CA1838: Avoid `StringBuilder` parameters for P/Invokes](ca1838.md) | Marshalling of `StringBuilder` always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. | > | [CA1839: Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName](ca1839.md) | `Environment.ProcessPath` is simpler and faster than `Process.GetCurrentProcess().MainModule.FileName`. | > | [CA1840: Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId](ca1840.md) | `Environment.CurrentManagedThreadId` is more compact and efficient than `Thread.CurrentThread.ManagedThreadId`. | > | [CA1841: Prefer Dictionary Contains methods](ca1841.md) | Calling `Contains` on the `Keys` or `Values` collection might often be more expensive than calling `ContainsKey` or `ContainsValue` on the dictionary itself. | -> | [CA1842: Do not use 'WhenAll' with a single task](ca1842.md) | Using `WhenAll` with a single task might result in performance loss. Await or return the task instead. | -> | [CA1843: Do not use 'WaitAll' with a single task](ca1843.md) | Using `WaitAll` with a single task might result in performance loss. Await or return the task instead. | -> | [CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'](ca1844.md) | To improve performance, override the memory-based async methods when subclassing 'Stream'. Then implement the array-based methods in terms of the memory-based methods. | -> | [CA1845: Use span-based 'string.Concat'](ca1845.md) | It is more efficient to use `AsSpan` and `string.Concat`, instead of `Substring` and a concatenation operator. | +> | [CA1842: Do not use `WhenAll` with a single task](ca1842.md) | Using `WhenAll` with a single task might result in performance loss. Await or return the task instead. | +> | [CA1843: Do not use `WaitAll` with a single task](ca1843.md) | Using `WaitAll` with a single task might result in performance loss. Await or return the task instead. | +> | [CA1844: Provide memory-based overrides of async methods when subclassing `Stream`](ca1844.md) | To improve performance, override the memory-based async methods when subclassing `Stream`. Then implement the array-based methods in terms of the memory-based methods. | +> | [CA1845: Use span-based `string.Concat`](ca1845.md) | It is more efficient to use `AsSpan` and `string.Concat`, instead of `Substring` and a concatenation operator. | > | [CA1846: Prefer `AsSpan` over `Substring`](ca1846.md) | `AsSpan` is more efficient than `Substring`. `Substring` performs an O(n) string copy, while `AsSpan` does not and has a constant cost. `AsSpan` also does not perform any heap allocations. | > | [CA1847: Use char literal for a single character lookup](ca1847.md) | Use `String.Contains(char)` instead of `String.Contains(string)` when searching for a single character. | > | [CA1848: Use the LoggerMessage delegates](ca1848.md) | For improved performance, use the `LoggerMessage` delegates. | @@ -155,24 +155,27 @@ The following table lists code quality analysis rules. > | [CA1850: Prefer static `HashData` method over `ComputeHash`](ca1850.md) | It's more efficient to use the static `HashData` method over creating and managing a `HashAlgorithm` instance to call `ComputeHash`. | > | [CA1851: Possible multiple enumerations of `IEnumerable` collection](ca1851.md) | Possible multiple enumerations of `IEnumerable` collection. Consider using an implementation that avoids multiple enumerations. | > | [CA1852: Seal internal types](ca1852.md) | A type that's not accessible outside its assembly and has no subtypes within its containing assembly is not sealed. | -> | [CA1853: Unnecessary call to 'Dictionary.ContainsKey(key)'](ca1853.md) | There's no need to guard `Dictionary.Remove(key)` with `Dictionary.ContainsKey(key)`. already checks whether the key exists and doesn't throw if it doesn't exist. | -> | [CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method](ca1854.md) | Prefer 'TryGetValue' over a Dictionary indexer access guarded by a 'ContainsKey' check. 'ContainsKey' and the indexer both look up the key, so using 'TryGetValue' avoids the extra lookup. | +> | [CA1853: Unnecessary call to `Dictionary.ContainsKey(key)`](ca1853.md) | There's no need to guard `Dictionary.Remove(key)` with `Dictionary.ContainsKey(key)`. already checks whether the key exists and doesn't throw if it doesn't exist. | +> | [CA1854: Prefer the `IDictionary.TryGetValue(TKey, out TValue)` method](ca1854.md) | Prefer `TryGetValue` over a Dictionary indexer access guarded by a `ContainsKey` check. `ContainsKey` and the indexer both look up the key, so using `TryGetValue` avoids the extra lookup. | > | [CA1855: Use Span\.Clear() instead of Span\.Fill()](ca1855.md) | It's more efficient to call than to call to fill the elements of the span with a default value. | > | [CA1856: Incorrect usage of ConstantExpected attribute](ca1856.md) | The attribute is not applied correctly on a parameter. | > | [CA1857: The parameter expects a constant for optimal performance](ca1857.md) | An invalid argument is passed to a parameter that's annotated with . | > | [CA1858: Use StartsWith instead of IndexOf](ca1858.md) | It's more efficient to call than to call to check whether a string starts with a given prefix. | > | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | -> | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | -> | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | -> | [CA1862: Use the 'StringComparison' method overloads to perform case-insensitive string comparisons](ca1862.md) | When code calls or to perform a case-insensitive string comparison, an unnecessary allocation is performed. | -> | [CA1863: Use 'CompositeFormat'](ca1863.md) | To reduce the formatting cost, cache and use a instance as the argument to `String.Format` or `StringBuilder.AppendFormat`. | -> | [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. `TryAdd` doesn't overwrite the key's value if the key is already present. | +> | [CA1860: Avoid using `Enumerable.Any()` extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | +> | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to `static readonly` fields to improve performance. | +> | [CA1862: Use the `StringComparison` method overloads to perform case-insensitive string comparisons](ca1862.md) | When code calls or to perform a case-insensitive string comparison, an unnecessary allocation is performed. | +> | [CA1863: Use `CompositeFormat`](ca1863.md) | To reduce the formatting cost, cache and use a instance as the argument to `String.Format` or `StringBuilder.AppendFormat`. | +> | [CA1864: Prefer the `IDictionary.TryAdd(TKey, TValue)` method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. `TryAdd` doesn't overwrite the key's value if the key is already present. | > | [CA1865-CA1867: Use char overload](ca1865-ca1867.md) | The char overload is a better performing overload for a string with a single char. | -> | [CA1868: Unnecessary call to 'Contains' for sets](ca1868.md) | Both and perform a lookup, which makes it redundant to call beforehand. It's more efficient to call or directly, which returns a Boolean value indicating whether the item was added or removed. | -> | [CA1869: Cache and reuse 'JsonSerializerOptions' instances](ca1869.md) | Using a local instance of for serialization or deserialization can substantially degrade the performance of your application if your code executes multiple times, since System.Text.Json internally caches serialization-related metadata into the provided instance. | -> | [CA1870: Use a cached 'SearchValues' instance](ca1870.md) | Using a cached instance is more efficient than passing values to 'IndexOfAny' or 'ContainsAny' directly. | -> | [CA1871: Do not pass a nullable struct to 'ArgumentNullException.ThrowIfNull'](ca1871.md) | 'ArgumentNullException.ThrowIfNull' accepts an 'object', so passing a nullable struct might cause the value to be boxed. | -> | [CA1872: Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString'](ca1872.md) | Use or when encoding bytes to a hexadecimal string representation. These methods are more efficient and allocation-friendly than using in combination with to replace dashes and . | +> | [CA1868: Unnecessary call to `Contains` for sets](ca1868.md) | Both and perform a lookup, which makes it redundant to call beforehand. It's more efficient to call or directly, which returns a Boolean value indicating whether the item was added or removed. | +> | [CA1869: Cache and reuse `JsonSerializerOptions` instances](ca1869.md) | Using a local instance of for serialization or deserialization can substantially degrade the performance of your application if your code executes multiple times, since System.Text.Json internally caches serialization-related metadata into the provided instance. | +> | [CA1870: Use a cached `SearchValues` instance](ca1870.md) | Using a cached instance is more efficient than passing values to `IndexOfAny` or `ContainsAny` directly. | +> | [CA1871: Do not pass a nullable struct to `ArgumentNullException.ThrowIfNull`](ca1871.md) | `ArgumentNullException.ThrowIfNull` accepts an `object`, so passing a nullable struct might cause the value to be boxed. | +> | [CA1872: Prefer `Convert.ToHexString` and `Convert.ToHexStringLower` over call chains based on `BitConverter.ToString`](ca1872.md) | Use or when encoding bytes to a hexadecimal string representation. These methods are more efficient and allocation-friendly than using in combination with to replace dashes and . | +> | [CA1873: Avoid potentially expensive logging](ca1873.md) | In many situations, logging is disabled or set to a log level that results in an unnecessary evaluation for logging arguments. | +> | [CA1874: Use `Regex.IsMatch`](ca1874.md) | `Regex.IsMatch` is simpler and faster than `Regex.Match(...).Success`. | +> | [CA1875: Use `Regex.Count`](ca1875.md) | `Regex.Count` is simpler and faster than `Regex.Matches(...).Count`. | > | [CA2000: Dispose objects before losing scope](ca2000.md) | Because an exceptional event might occur that will prevent the finalizer of an object from running, the object should be explicitly disposed before all references to it are out of scope. | > | [CA2002: Do not lock on objects with weak identity](ca2002.md) |An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | > | [CA2007: Do not directly await a Task](ca2007.md) | An asynchronous method [awaits](../../../csharp/language-reference/operators/await.md) a directly. When an asynchronous method awaits a directly, continuation occurs in the same thread that created the task. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling to signal your intention for continuation. | @@ -190,6 +193,7 @@ The following table lists code quality analysis rules. > | [CA2020: Prevent behavioral change caused by built-in operators of IntPtr/UIntPtr](ca2020.md) | Some built-in operators added in .NET 7 behave differently than the user-defined operators in .NET 6 and earlier versions. Some operators that used to throw in unchecked context while overflowing don't throw anymore unless wrapped within checked context. Some operators that previously didn't throw in checked context now throw unless wrapped within unchecked context. | > | [CA2021: Don't call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types](ca2021.md) | A call to or specifies a type parameter that's incompatible with the type of the input collection. | > | [CA2022: Avoid inexact read with Stream.Read](ca2022.md) | A call to `Stream.Read` might return fewer bytes than requested, resulting in unreliable code if the return value isn't checked. | +> | [CA2023: Invalid braces in message template](ca2023.md) | The braces present in the message template are invalid. Ensure any braces in the message template are valid opening/closing braces, or are escaped. | > | [CA2024: Do not use StreamReader.EndOfStream in async methods](ca2024.md) | The property can cause unintended synchronous blocking when no data is buffered. Instead, use directly, which returns `null` when reaching the end of the stream. | > | [CA2025: Do not pass `IDisposable` instances into unawaited tasks](ca2025.md) | Unawaited tasks that use `IDisposable` instances might use those instances long after they have been disposed. Ensure tasks using those instances are completed before the instances are disposed. | > | [CA2100: Review SQL queries for security vulnerabilities](ca2100.md) | A method sets the System.Data.IDbCommand.CommandText property by using a string that is built from a string argument to the method. This rule assumes that the string argument contains user input. A SQL command string that is built from user input is vulnerable to SQL injection attacks. | @@ -234,14 +238,14 @@ The following table lists code quality analysis rules. > | [CA2254: Template should be a static expression](ca2254.md) | The logging message template should not vary between calls. | > | [CA2255: The `ModuleInitializer` attribute should not be used in libraries](ca2255.md) | Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. | > | [CA2256: All members declared in parent interfaces must have an implementation in a DynamicInterfaceCastableImplementation-attributed interface](ca2256.md) | Types attributed with `DynamicInterfaceCastableImplementationAttribute` act as an interface implementation for a type that implements the `IDynamicInterfaceCastable` type. As a result, it must provide an implementation of all of the members defined in the inherited interfaces, because the type that implements `IDynamicInterfaceCastable` will not provide them otherwise. | -> | [CA2257: Members defined on an interface with 'DynamicInterfaceCastableImplementationAttribute' should be 'static'](ca2257.md) | Since a type that implements `IDynamicInterfaceCastable` might not implement a dynamic interface in metadata, calls to an instance interface member that is not an explicit implementation defined on this type are likely to fail at run time. Mark new interface members `static` to avoid run-time errors. | -> | [CA2258: Providing a 'DynamicInterfaceCastableImplementation' interface in Visual Basic is unsupported](ca2258.md) | Providing a functional `DynamicInterfaceCastableImplementationAttribute`-attributed interface requires the Default Interface Members feature, which is unsupported in Visual Basic. | +> | [CA2257: Members defined on an interface with `DynamicInterfaceCastableImplementationAttribute` should be `static`](ca2257.md) | Since a type that implements `IDynamicInterfaceCastable` might not implement a dynamic interface in metadata, calls to an instance interface member that is not an explicit implementation defined on this type are likely to fail at run time. Mark new interface members `static` to avoid run-time errors. | +> | [CA2258: Providing a `DynamicInterfaceCastableImplementation` interface in Visual Basic is unsupported](ca2258.md) | Providing a functional `DynamicInterfaceCastableImplementationAttribute`-attributed interface requires the Default Interface Members feature, which is unsupported in Visual Basic. | > | [CA2259: Ensure `ThreadStatic` is only used with static fields](ca2259.md) | only affects `static` (`Shared` in Visual Basic) fields. When applied to instance fields, the attribute has no impact on behavior. | > | [CA2260: Implement generic math interfaces correctly](ca2260.md) | Generic math interfaces require the derived type itself to be used for the self-recurring type parameter. | > | [CA2261: Do not use `ConfigureAwaitOptions.SuppressThrowing` with `Task`](ca2261.md) | The `ConfigureAwaitOptions.SuppressThrowing` option isn't supported by the generic `Task`, since that might lead to returning an invalid `TResult`. | > | [CA2262: Set `MaxResponseHeadersLength` properly](ca2262.md) | Make sure the `MaxResponseHeadersLength` value is provided correctly. This value is measured in kilobytes. | > | [CA2263: Prefer generic overload when type is known](ca2263.md) | Using a generic overload is preferable to passing a argument when the type is known, because they promote cleaner and more type-safe code with improved compile-time checks. | -> | [CA2264: Do not pass a non-nullable value to 'ArgumentNullException.ThrowIfNull'](ca2264.md) | 'ArgumentNullException.ThrowIfNull' throws when the passed argument is 'null'. Certain constructs like non-nullable structs, and 'nameof()' and 'new' expressions are known to never be null, so 'ArgumentNullException.ThrowIfNull' will never throw. | +> | [CA2264: Do not pass a non-nullable value to `ArgumentNullException.ThrowIfNull`](ca2264.md) | `ArgumentNullException.ThrowIfNull` throws when the passed argument is `null`. Certain constructs like non-nullable structs, and `nameof()` and `new` expressions are known to never be null, so `ArgumentNullException.ThrowIfNull` will never throw. | > | [CA2265: Do not compare `Span` to `null` or `default`](ca2265.md) | Comparing a span to `null` or `default` might not do what you intended. `default` and the `null` literal are implicitly converted to `Span.Empty`. | > | [CA2300: Do not use insecure deserializer BinaryFormatter](ca2300.md) | Insecure deserializers are vulnerable when deserializing untrusted data. An attacker could modify the serialized data to include unexpected types to inject objects with malicious side effects. | > | [CA2301: Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder](ca2301.md) | Insecure deserializers are vulnerable when deserializing untrusted data. An attacker could modify the serialized data to include unexpected types to inject objects with malicious side effects. | @@ -336,23 +340,23 @@ The following table lists code quality analysis rules. > | [CA5405: Do not always skip token validation in delegates](ca5405.md) | The callback assigned to `AudienceValidator` or `LifetimeValidator` always returns `true`. | > | [IL3000: Avoid accessing Assembly file path when publishing as a single file](../../../core/deploying/single-file/warnings/il3000.md) | Avoid accessing Assembly file path when publishing as a single file. | > | [IL3001: Avoid accessing Assembly file path when publishing as a single-file](../../../core/deploying/single-file/warnings/il3001.md) | Avoid accessing Assembly file path when publishing as a single file. | -> | [IL3002: Avoid calling members annotated with 'RequiresAssemblyFilesAttribute' when publishing as a single file](../../../core/deploying/single-file/warnings/il3002.md) | Avoid calling members annotated with 'RequiresAssemblyFilesAttribute' when publishing as a single file| -> | [IL3003: 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.](../../../core/deploying/single-file/warnings/il3003.md) | 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.| +> | [IL3002: Avoid calling members annotated with `RequiresAssemblyFilesAttribute` when publishing as a single file](../../../core/deploying/single-file/warnings/il3002.md) | Avoid calling members annotated with `RequiresAssemblyFilesAttribute` when publishing as a single file| +> | [IL3003: `RequiresAssemblyFilesAttribute` annotations must match across all interface implementations or overrides.](../../../core/deploying/single-file/warnings/il3003.md) | `RequiresAssemblyFilesAttribute` annotations must match across all interface implementations or overrides.| > | [IL3005: `RequiresAssemblyFilesAttribute` cannot be placed directly on application entry point.](../../../core/deploying/single-file/warnings/il3005.md)|`RequiresAssemblyFilesAttribute` cannot be placed directly on application entry point. | ## Legend The following table shows the type of information that is provided for each rule in the reference documentation. -|Item|Description| -|----------|-----------------| -|Type|The TypeName for the rule.| -| **Rule ID** |The unique identifier for the rule. RuleId and Category are used for in-source suppression of a warning.| -| **Category** |The category of the rule, for example, security.| -| **Fix is breaking or non-breaking** |Whether the fix for a violation of the rule is a breaking change. Breaking change means that an assembly that has a dependency on the target that caused the violation will not recompile with the new fixed version or might fail at run time because of the change. When multiple fixes are available and at least one fix is a breaking change and one fix is not, both 'Breaking' and 'Non-breaking' are specified.| -|Cause|The specific managed code that causes the rule to generate a warning.| -|Description|Discusses the issues that are behind the warning.| -|How to fix violations|Explains how to change the source code to satisfy the rule and prevent it from generating a warning.| -|When to suppress warnings|Describes when it is safe to suppress a warning from the rule.| -|Example code|Examples that violate the rule and corrected examples that satisfy the rule.| -|Related rules|Related rules.| +| Item | Description | +|--------------|--------------------------------------------------| +| Type | The TypeName for the rule. | +| **Rule ID** | The unique identifier for the rule. RuleId and Category are used for in-source suppression of a warning. | +| **Category** | The category of the rule, for example, security. | +| **Fix is breaking or non-breaking** | Whether the fix for a violation of the rule is a breaking change. Breaking change means that an assembly that has a dependency on the target that caused the violation will not recompile with the new fixed version or might fail at run time because of the change. When multiple fixes are available and at least one fix is a breaking change and one fix is not, both 'Breaking' and 'Non-breaking' are specified. | +| Cause | The specific managed code that causes the rule to generate a warning. | +| Description | Discusses the issues that are behind the warning. | +| How to fix violations | Explains how to change the source code to satisfy the rule and prevent it from generating a warning. | +| When to suppress warnings | Describes when it is safe to suppress a warning from the rule. | +| Example code | Examples that violate the rule and corrected examples that satisfy the rule. | +| Related rules | Related rules. | diff --git a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md index dc28cd1200fb5..d46d9b9608e87 100644 --- a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md +++ b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md @@ -1,7 +1,7 @@ --- title: Performance rules (code analysis) description: "Learn about code analysis performance rules." -ms.date: 11/15/2023 +ms.date: 10/27/2025 f1_keywords: - vs.codeanalysis.performancerules helpviewer_keywords: @@ -19,7 +19,7 @@ Performance rules support high-performance libraries and applications. ## In this section | Rule | Description | -| - | - | +|------|-------------| | [CA1802: Use Literals Where Appropriate](ca1802.md) | A field is declared static and read-only (Shared and ReadOnly in Visual Basic), and is initialized with a value that is computable at compile time. Because the value that is assigned to the targeted field is computable at compile time, change the declaration to a const (Const in Visual Basic) field so that the value is computed at compile time instead of at run time. | | [CA1805: Do not initialize unnecessarily](ca1805.md) | The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size). | | [CA1806: Do not ignore method results](ca1806.md) | A new object is created but never used, or a method that creates and returns a new string is called and the new string is never used, or a Component Object Model (COM) or P/Invoke method returns an HRESULT or error code that is never used. | @@ -80,3 +80,6 @@ Performance rules support high-performance libraries and applications. | [CA1870: Use a cached 'SearchValues' instance](ca1870.md) | Using a cached instance is more efficient than passing values to 'IndexOfAny' or 'ContainsAny' directly. | | [CA1871: Do not pass a nullable struct to 'ArgumentNullException.ThrowIfNull'](ca1871.md) | 'ArgumentNullException.ThrowIfNull' accepts an 'object', so passing a nullable struct might cause the value to be boxed. | | [CA1872: Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString'](ca1872.md) | Use or when encoding bytes to a hexadecimal string representation. These methods are more efficient and allocation-friendly than using in combination with to replace dashes and . | +| [CA1873: Avoid potentially expensive logging](ca1873.md) | 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 or use the `LoggerMessage` pattern. | +| [CA1874: Use 'Regex.IsMatch'](ca1874.md) | is simpler and faster than `Regex.Match(...).Success`. | +| [CA1875: Use 'Regex.Count'](ca1875.md) | is simpler and faster than `Regex.Matches(...).Count`. | diff --git a/docs/fundamentals/code-analysis/quality-rules/reliability-warnings.md b/docs/fundamentals/code-analysis/quality-rules/reliability-warnings.md index 37a93a288af35..6437efebefa8a 100644 --- a/docs/fundamentals/code-analysis/quality-rules/reliability-warnings.md +++ b/docs/fundamentals/code-analysis/quality-rules/reliability-warnings.md @@ -1,22 +1,20 @@ --- title: Reliability rules (code analysis) description: "Learn about code analysis reliability rules." -ms.date: 11/16/2023 +ms.date: 10/27/2025 f1_keywords: - vs.codeanalysis.reliabilityrules helpviewer_keywords: - rules, reliability - reliability rules - managed code analysis rules, reliability rules -author: gewarren -ms.author: gewarren --- # Reliability rules Reliability rules support library and application reliability, such as correct memory and thread usage. The reliability rules include: -|Rule|Description| -|----------|-----------------| +| Rule | Description | +|------|-------------| | [CA2000: Dispose objects before losing scope](ca2000.md) | Because an exceptional event might occur that will prevent the finalizer of an object from running, the object should be explicitly disposed before all references to it are out of scope. | | [CA2002: Do not lock on objects with weak identity](ca2002.md) | An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | | [CA2007: Do not directly await a Task](ca2007.md) | An asynchronous method [awaits](../../../csharp/language-reference/operators/await.md) a directly. | @@ -34,5 +32,6 @@ Reliability rules support library and application reliability, such as correct m | [CA2020: Prevent behavioral change caused by built-in operators of IntPtr/UIntPtr](ca2020.md) | Some built-in operators added in .NET 7 behave differently than the user-defined operators in .NET 6 and earlier versions. Some operators that used to throw in unchecked context while overflowing don't throw anymore unless wrapped within checked context. Some operators that previously didn't throw in checked context now throw unless wrapped within unchecked context. | | [CA2021: Don't call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types](ca2021.md) | A call to or specifies a type parameter that's incompatible with the type of the input collection. | | [CA2022: Avoid inexact read with Stream.Read](ca2022.md) | A call to `Stream.Read` might return fewer bytes than requested, resulting in unreliable code if the return value isn't checked. | +| [CA2023: Invalid braces in message template](ca2023.md) | Logging message templates use curly braces `{` and `}` to denote named placeholders for values. Invalid brace usage in message templates can result in runtime exceptions or unexpected logging behavior. | | [CA2024: Do not use StreamReader.EndOfStream in async methods](ca2024.md) | The property can cause unintended synchronous blocking when no data is buffered. Instead, use directly, which returns `null` when reaching the end of the stream. | | [CA2025: Do not pass `IDisposable` instances into unawaited tasks](ca2025.md) | Unawaited tasks that use `IDisposable` instances might use those instances long after they have been disposed. Ensure tasks using those instances are completed before the instances are disposed. | diff --git a/docs/navigate/tools-diagnostics/toc.yml b/docs/navigate/tools-diagnostics/toc.yml index c9a3ddc0e8082..629a2c1d8e076 100644 --- a/docs/navigate/tools-diagnostics/toc.yml +++ b/docs/navigate/tools-diagnostics/toc.yml @@ -3281,6 +3281,12 @@ items: href: ../../fundamentals/code-analysis/quality-rules/ca1871.md - name: CA1872 href: ../../fundamentals/code-analysis/quality-rules/ca1872.md + - name: CA1873 + href: ../../fundamentals/code-analysis/quality-rules/ca1873.md + - name: CA1874 + href: ../../fundamentals/code-analysis/quality-rules/ca1874.md + - name: CA1875 + href: ../../fundamentals/code-analysis/quality-rules/ca1875.md - name: SingleFile rules items: - name: Overview @@ -3335,6 +3341,8 @@ items: href: ../../fundamentals/code-analysis/quality-rules/ca2021.md - name: CA2022 href: ../../fundamentals/code-analysis/quality-rules/ca2022.md + - name: CA2023 + href: ../../fundamentals/code-analysis/quality-rules/ca2023.md - name: CA2024 href: ../../fundamentals/code-analysis/quality-rules/ca2024.md - name: CA2025