From 308af6466a8ef7c267f18c54a7acf7bb94cf6d2a Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 7 Jul 2026 11:43:18 -0500 Subject: [PATCH 01/26] Document DOTNET_CLI_ENABLEAOT environment variable (#54649) * Document DOTNET_CLI_ENABLEAOT environment variable Adds the DOTNET_CLI_ENABLEAOT variable (NativeAOT CLI command-handling fast path, enabled by default) to the .NET SDK and CLI environment variables reference. Fixes #54648 * Note macOS exclusion for DOTNET_CLI_ENABLEAOT The fast path is disabled by default on macOS pending dotnet/command-line-api#2812. * Update DOTNET_CLI_ENABLEAOT: default-on Windows only (macOS + Linux blocked by command-line-api#2812) * DOTNET_CLI_ENABLEAOT: rework flow and move default-platform caveat into a Note * DOTNET_CLI_ENABLEAOT: note that Windows default becomes true in .NET 11 Preview 7 --- docs/core/tools/dotnet-environment-variables.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/core/tools/dotnet-environment-variables.md b/docs/core/tools/dotnet-environment-variables.md index 3db2af9a1a1c3..141dcafcef2c3 100644 --- a/docs/core/tools/dotnet-environment-variables.md +++ b/docs/core/tools/dotnet-environment-variables.md @@ -192,6 +192,7 @@ This section describes the following environment variables: - [`DOTNET_SERVICING`](#dotnet_servicing) - [`DOTNET_NOLOGO`](#dotnet_nologo) - [`DOTNET_CLI_PERF_LOG`](#dotnet_cli_perf_log) +- [`DOTNET_CLI_ENABLEAOT`](#dotnet_cli_enableaot) - [`DOTNET_GENERATE_ASPNET_CERTIFICATE`](#dotnet_generate_aspnet_certificate) - [`DOTNET_ADD_GLOBAL_TOOLS_TO_PATH`](#dotnet_add_global_tools_to_path) - [`DOTNET_CLI_TELEMETRY_OPTOUT`](#dotnet_cli_telemetry_optout) @@ -324,6 +325,18 @@ Specifies whether .NET welcome and telemetry messages are displayed on the first Specifies whether performance details about the current CLI session are logged. Enabled when set to `1`, `true`, or `yes`. This is disabled by default. +### `DOTNET_CLI_ENABLEAOT` + +Specifies whether the .NET SDK uses its native (ahead-of-time compiled) CLI command-handling fast path. When enabled, common commands (such as command-line parsing, `dotnet --version`, and `dotnet --info`) are handled by a native entry point for faster startup, transparently falling back to the managed CLI for anything the fast path doesn't handle. + +Set this variable to control the fast path explicitly: + +- To enable it, set the variable to `true`, `1`, `yes`, or `on`. +- To disable it and route every invocation to the managed CLI, set the variable to `false`, `0`, `no`, or `off`. + +> [!NOTE] +> Starting in .NET 11 Preview 7, this fast path is enabled by default (`true`) on Windows. On macOS and Linux it's disabled by default because of a command-line parsing issue ([dotnet/command-line-api#2812](https://github.com/dotnet/command-line-api/issues/2812)): when the native CLI is loaded as a NativeAOT shared library, `Environment.GetCommandLineArgs()` returns an empty array on those platforms, which causes command-line parsing to throw. It will be enabled by default on macOS and Linux once that issue is resolved. In the meantime, you can opt in early on those platforms by setting the variable to a value that enables it. + ### `DOTNET_GENERATE_ASPNET_CERTIFICATE` Specifies whether to generate an ASP.NET Core certificate. The default value is `true`, but this can be overridden by setting this environment variable to either `0`, `false`, or `no`. From db6a7bc70a24c6e4000536c2d1f679bc8fd9f3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 7 Jul 2026 18:53:10 +0200 Subject: [PATCH 02/26] Document MSTest and MTP feature versions (#54408) * Document MSTest and MTP feature versions Analyze MSTest (3.6-4.2) and Microsoft.Testing.Platform (1.5-2.3) features against the microsoft/testfx changelogs and add missing "introduced in" version annotations, document previously undocumented features, and correct stale content (TRX default filename, removed ITestApplicationLifecycleCallbacks, testconfig.json CLI-option support). All new xref IDs verified against the .NET API catalog; markdownlint clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Factor out report file-name placeholders and document defaults Add a shared 'Report file names' section listing the placeholder set and link each --report-*-filename option to it. State the default file name for TRX, HTML, JUnit, and CTRF reports (verified from testfx source), and note the HTML/JUnit/CTRF extensions are experimental. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document MSTEST0047 suppressor and new Azure DevOps report options Add the missing MSTEST0047 (suppress IDE0060 for the TestContext parameter of fixture methods, introduced in MSTest 3.10) analyzer page, and reference it from the analyzers overview, suppression rules list, and TOC. Document the new --report-azdo-summary and --report-azdo-stackframe-filter options (MTP 2.3.0). Verified against microsoft/testfx source. Markdownlint clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback: anchor links and field-source wording Fix three ITestHostProcessLifetimeHandler sequence links that pointed to the wrong section anchor, and clarify that field data sources require MSTest 3.11. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- ...esting-platform-architecture-extensions.md | 35 ++++--- .../microsoft-testing-platform-cli-options.md | 8 +- .../microsoft-testing-platform-config.md | 37 +++++-- ...crosoft-testing-platform-open-telemetry.md | 5 +- ...icrosoft-testing-platform-run-and-debug.md | 7 +- ...rosoft-testing-platform-terminal-output.md | 8 +- ...microsoft-testing-platform-test-reports.md | 99 ++++++++++++++++++- .../testing/mstest-analyzers/mstest0047.md | 32 ++++++ .../core/testing/mstest-analyzers/overview.md | 2 + .../mstest-analyzers/suppression-rules.md | 22 +++++ .../testing/unit-testing-mstest-configure.md | 5 +- ...testing-mstest-writing-tests-assertions.md | 24 +++++ ...est-writing-tests-controlling-execution.md | 13 ++- ...esting-mstest-writing-tests-data-driven.md | 43 +++++++- ...-testing-mstest-writing-tests-lifecycle.md | 5 +- ...testing-mstest-writing-tests-organizing.md | 6 +- ...esting-mstest-writing-tests-testcontext.md | 9 +- docs/navigate/devops-testing/toc.yml | 2 + 18 files changed, 323 insertions(+), 39 deletions(-) create mode 100644 docs/core/testing/mstest-analyzers/mstest0047.md diff --git a/docs/core/testing/microsoft-testing-platform-architecture-extensions.md b/docs/core/testing/microsoft-testing-platform-architecture-extensions.md index 4bcd1417fd33a..aa32c4872d13e 100644 --- a/docs/core/testing/microsoft-testing-platform-architecture-extensions.md +++ b/docs/core/testing/microsoft-testing-platform-architecture-extensions.md @@ -3,7 +3,7 @@ title: Build extensions for Microsoft.Testing.Platform (MTP) description: Learn how to create in-process and out-of-process extensions for Microsoft.Testing.Platform (MTP). author: MarcoRossignoli ms.author: mrossignoli -ms.date: 06/02/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -206,35 +206,38 @@ If your extension requires intensive initialization and you need to use the asyn ### The `ITestApplicationLifecycleCallbacks` extensions -The `ITestApplicationLifecycleCallbacks` is an *in-process* extension that enables the execution of code before everything, it's like to have access to the first line of the hypothetical *main* of the *test host*. +> [!IMPORTANT] +> `ITestApplicationLifecycleCallbacks` was removed in MTP 2.0.0. Use `ITestHostApplicationLifetime` instead. For more information, see [Migrate from Microsoft.Testing.Platform (MTP) v1 to v2](microsoft-testing-platform-migration-from-v1-to-v2.md#removed-obsolete-types). + +The `ITestHostApplicationLifetime` interface lets an *in-process* extension run code at the start and end of the *test host*. -To register a custom `ITestApplicationLifecycleCallbacks`, utilize the following api: +To register a custom `ITestHostApplicationLifetime`, use the following API: ```csharp var builder = await TestApplication.CreateBuilderAsync(args); // ... -builder.TestHost.AddTestApplicationLifecycleCallbacks( +builder.TestHost.AddTestHostApplicationLifetime( static serviceProvider - => new CustomTestApplicationLifecycleCallbacks()); + => new CustomTestHostApplicationLifetime()); ``` -The factory utilizes the [IServiceProvider](./microsoft-testing-platform-architecture-services.md#the-imessagebus-service) to gain access to the suite of services offered by the testing platform. +The factory uses the [IServiceProvider](./microsoft-testing-platform-architecture-services.md#the-imessagebus-service) to access the services offered by the testing platform. > [!IMPORTANT] > The sequence of registration is significant, as the APIs are called in the order they were registered. -The `ITestApplicationLifecycleCallbacks` interface includes the following methods: +The `ITestHostApplicationLifetime` interface includes the following methods: ```csharp -public interface ITestApplicationLifecycleCallbacks : ITestHostExtension +public interface ITestHostApplicationLifetime : ITestHostExtension { Task BeforeRunAsync(CancellationToken cancellationToken); Task AfterRunAsync( int exitCode, - CancellationToken cancellation); + CancellationToken cancellationToken); } public interface ITestHostExtension : IExtension @@ -242,7 +245,7 @@ public interface ITestHostExtension : IExtension } ``` -The `ITestApplicationLifecycleCallbacks` is a type of `ITestHostExtension`, which serves as a base for all *test host* extensions. Like all other extension points, it also inherits from [IExtension](./microsoft-testing-platform-architecture-test-framework.md#the-iextension-interface). Therefore, like any other extension, you can choose to enable or disable it using the `IExtension.IsEnabledAsync` API. +The `ITestHostApplicationLifetime` interface extends `ITestHostExtension`, which serves as a base for all *test host* extensions. Like all other extension points, it also inherits from [IExtension](./microsoft-testing-platform-architecture-test-framework.md#the-iextension-interface). Therefore, like any other extension, you can choose to enable or disable it using the `IExtension.IsEnabledAsync` API. `BeforeRunAsync`: This method serves as the initial point of contact for the *test host* and is the first opportunity for an *in-process* extension to execute a feature. It's typically used to establish a connection with any corresponding *out-of-process* extensions if a feature is designed to operate across both environments. @@ -492,7 +495,7 @@ Consider the following details for this API: `OnTestHostProcessStartedAsync`: This method is invoked immediately after the test host starts. This method offers an object that implements the `ITestHostProcessInformation` interface, which provides key details about the test host process result. > [!IMPORTANT] -> The invocation of this method does not halt the test host's execution. If you need to pause it, you should register an [*in-process*](./microsoft-testing-platform-architecture.md#in-process-vs-out-of-process-extensions) extension such as [`ITestApplicationLifecycleCallbacks`](#the-itestapplicationlifecyclecallbacks-extensions) and synchronize it with the *out-of-process* extension. +> The invocation of this method does not halt the test host's execution. If you need to pause it, you should register an [*in-process*](./microsoft-testing-platform-architecture.md#in-process-vs-out-of-process-extensions) extension such as [`ITestHostApplicationLifetime`](#the-itestapplicationlifecyclecallbacks-extensions) and synchronize it with the *out-of-process* extension. `OnTestHostProcessExitedAsync`: This method is invoked when the test suite execution is complete. This method supplies an object that adheres to the `ITestHostProcessInformation` interface, which conveys crucial details about the outcome of the test host process. @@ -595,18 +598,18 @@ The testing platform consists of a [testing framework](./microsoft-testing-platf 1. [ITestHostEnvironmentVariableProvider.UpdateAsync](#the-itesthostenvironmentvariableprovider-extensions) : Out-of-process 1. [ITestHostEnvironmentVariableProvider.ValidateTestHostEnvironmentVariablesAsync](#the-itesthostenvironmentvariableprovider-extensions) : Out-of-process -1. [ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync](#the-itestsessionlifetimehandler-extensions) : Out-of-process +1. [ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync](#the-itesthostprocesslifetimehandler-extensions) : Out-of-process 1. Test host process start -1. [ITestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync](#the-itestsessionlifetimehandler-extensions) : Out-of-process, this event can intertwine the actions of *in-process* extensions, depending on race conditions. -1. [ITestApplicationLifecycleCallbacks.BeforeRunAsync](#the-itestsessionlifetimehandler-extensions): In-process +1. [ITestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync](#the-itesthostprocesslifetimehandler-extensions) : Out-of-process, this event can intertwine the actions of *in-process* extensions, depending on race conditions. +1. [ITestHostApplicationLifetime.BeforeRunAsync](#the-itestapplicationlifecyclecallbacks-extensions): In-process 1. [ITestSessionLifetimeHandler.OnTestSessionStartingAsync](#the-itestsessionlifetimehandler-extensions): In-process 1. [ITestFramework.CreateTestSessionAsync](./microsoft-testing-platform-architecture-test-framework.md#test-framework-extension): In-process 1. [ITestFramework.ExecuteRequestAsync](./microsoft-testing-platform-architecture-test-framework.md#test-framework-extension): In-process, this method can be called one or more times. At this point, the testing framework will transmit information to the [IMessageBus](./microsoft-testing-platform-architecture-services.md#the-imessagebus-service) that can be utilized by the [IDataConsumer](#the-idataconsumer-extensions). 1. [ITestFramework.CloseTestSessionAsync](./microsoft-testing-platform-architecture-test-framework.md#test-framework-extension): In-process 1. [ITestSessionLifetimeHandler.OnTestSessionFinishingAsync](#the-itestsessionlifetimehandler-extensions): In-process -1. [ITestApplicationLifecycleCallbacks.AfterRunAsync](#the-itestsessionlifetimehandler-extensions): In-process +1. [ITestHostApplicationLifetime.AfterRunAsync](#the-itestapplicationlifecyclecallbacks-extensions): In-process 1. In-process cleanup, involves calling dispose and [IAsyncCleanableExtension](#asynchronous-initialization-and-cleanup-of-extensions) on all extension points. -1. [ITestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync](#the-itestsessionlifetimehandler-extensions) : Out-of-process +1. [ITestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync](#the-itesthostprocesslifetimehandler-extensions) : Out-of-process 1. Out-of-process cleanup, involves calling dispose and [IAsyncCleanableExtension](#asynchronous-initialization-and-cleanup-of-extensions) on all extension points. ## Extensions helpers diff --git a/docs/core/testing/microsoft-testing-platform-cli-options.md b/docs/core/testing/microsoft-testing-platform-cli-options.md index d3d557b164038..5d018601b41c4 100644 --- a/docs/core/testing/microsoft-testing-platform-cli-options.md +++ b/docs/core/testing/microsoft-testing-platform-cli-options.md @@ -3,7 +3,7 @@ title: Microsoft.Testing.Platform (MTP) CLI options reference description: Find platform and extension command-line options for MTP in one place. author: Evangelink ms.author: amauryleve -ms.date: 06/01/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -68,6 +68,9 @@ This article gives a central entry point for MTP command-line options. Forces the built-in file logger to synchronously write logs. Useful for scenarios where you don't want to lose any log entries (if the process crashes). This slows down the test execution. + > [!NOTE] + > Available in MTP starting with version 2.0.0. It replaces the previous `--diagnostic-filelogger-synchronouswrite` option, which was removed in MTP 2.0.0. + - **`--diagnostic-output-directory`** The output directory of the diagnostic logging, if not specified the file is generated in the default _TestResults_ directory. @@ -76,6 +79,9 @@ This article gives a central entry point for MTP command-line options. The prefix for the log file name. Defaults to `"log"`. + > [!NOTE] + > Available in MTP starting with version 2.0.0. It replaces the previous `--diagnostic-output-fileprefix` option, which was removed in MTP 2.0.0. + - **`--diagnostic-verbosity`** Defines the verbosity level when the `--diagnostic` switch is used. The available values are `Trace`, `Debug`, `Information`, `Warning`, `Error`, or `Critical`. diff --git a/docs/core/testing/microsoft-testing-platform-config.md b/docs/core/testing/microsoft-testing-platform-config.md index 82d94a17eba9a..a83e147ffb9cb 100644 --- a/docs/core/testing/microsoft-testing-platform-config.md +++ b/docs/core/testing/microsoft-testing-platform-config.md @@ -3,7 +3,7 @@ title: Microsoft.Testing.Platform (MTP) config options description: Learn how to configure MTP using testconfig.json configuration settings and environment variables. author: Evangelink ms.author: amauryleve -ms.date: 06/01/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -78,9 +78,27 @@ Example: } ``` -### Extension options are CLI-only +### Environment variables in testconfig.json -Extension features such as [crash dump](microsoft-testing-platform-crash-hang-dumps.md), [hang dump](microsoft-testing-platform-crash-hang-dumps.md), [retry](microsoft-testing-platform-retry.md), [TRX reports](microsoft-testing-platform-test-reports.md), and [code coverage](microsoft-testing-platform-code-coverage.md) are **not** configurable via *testconfig.json*. These features are configured exclusively through command-line arguments. +> [!NOTE] +> Available in MTP starting with version 2.3.0. + +The `environmentVariables` section sets environment variables for the test process before it starts. Use string values for each variable. + +```json +{ + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development", + "FEATURE_FLAG": "true" + } +} +``` + +### CLI options in testconfig.json + +Before MTP 2.3.0, extension features such as [crash dump](microsoft-testing-platform-crash-hang-dumps.md), [hang dump](microsoft-testing-platform-crash-hang-dumps.md), [retry](microsoft-testing-platform-retry.md), [TRX reports](microsoft-testing-platform-test-reports.md), and [code coverage](microsoft-testing-platform-code-coverage.md) aren't configurable via *testconfig.json*. These features are configured exclusively through command-line arguments. + +Starting with MTP 2.3.0, MTP can read CLI options from *testconfig.json* through `IConfiguration`. This support includes extension options, so you can use JSON entries for options that you don't want to pass on the command line each run. Command-line arguments still take precedence. For a complete reference of command-line options, see [MTP CLI options reference](microsoft-testing-platform-cli-options.md). @@ -128,9 +146,9 @@ If you're migrating from a *.runsettings* file, the following table maps common | `RunConfiguration/MaxCpuCount` | No equivalent | Process-level parallelism is controlled by `dotnet test --max-parallel-test-modules` or MSBuild `/m` option. | | `MSTest/*` | `mstest.*` | See [Configure MSTest — testconfig.json](unit-testing-mstest-configure.md#testconfigjson). | | `xUnit/*` | `xUnit.*` | See [xUnit.net testconfig.json](https://xunit.net/docs/config-testconfig-json). | -| `LoggerRunSettings/Loggers` | CLI only | Use `--report-trx` or similar CLI options. | -| `DataCollectionRunSettings` (blame) | CLI only | Use `--crashdump` and `--hangdump` CLI options. See [Crash and hang dumps](microsoft-testing-platform-crash-hang-dumps.md). | -| `DataCollectionRunSettings` (coverage) | CLI only | Use `--coverage` CLI option. See [Code coverage](microsoft-testing-platform-code-coverage.md). | +| `LoggerRunSettings/Loggers` | CLI options | Use `--report-trx` or similar CLI options. Starting with MTP 2.3.0, MTP can read CLI options from *testconfig.json*. | +| `DataCollectionRunSettings` (blame) | CLI options | Use `--crashdump` and `--hangdump` CLI options. Starting with MTP 2.3.0, MTP can read CLI options from *testconfig.json*. See [Crash and hang dumps](microsoft-testing-platform-crash-hang-dumps.md). | +| `DataCollectionRunSettings` (coverage) | CLI options | Use `--coverage` CLI option. Starting with MTP 2.3.0, MTP can read CLI options from *testconfig.json*. See [Code coverage](microsoft-testing-platform-code-coverage.md). | | `TestRunParameters` | `--test-parameter` CLI | Use `--test-parameter key=value` on the command line. | ## Environment variables @@ -186,6 +204,13 @@ A semicolon-separated list of exit codes to ignore. When an exit code is ignored When set to `1` or `true`, suppresses the startup banner, the copyright message, and the telemetry banner. Equivalent to the `--no-banner` command-line option. The `DOTNET_NOLOGO` environment variable has the same effect. +### `NO_COLOR` environment variable + +When set to any non-empty value, suppresses all ANSI color output. MTP honors the [`NO_COLOR`](https://no-color.org/) convention. + +> [!NOTE] +> Available in MTP starting with version 2.3.0. + ### `DOTNET_NOLOGO` environment variable When set to `1` or `true`, suppresses the startup banner, the copyright message, and the telemetry banner. This is the standard .NET CLI environment variable and is honored by MTP. See also `TESTINGPLATFORM_NOBANNER`. diff --git a/docs/core/testing/microsoft-testing-platform-open-telemetry.md b/docs/core/testing/microsoft-testing-platform-open-telemetry.md index 21a04b336e5e1..97781093d81a9 100644 --- a/docs/core/testing/microsoft-testing-platform-open-telemetry.md +++ b/docs/core/testing/microsoft-testing-platform-open-telemetry.md @@ -3,7 +3,7 @@ title: Microsoft.Testing.Platform (MTP) OpenTelemetry description: Learn how to use the OpenTelemetry extension to emit traces and metrics from MTP. author: Evangelink ms.author: amauryleve -ms.date: 02/25/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -13,6 +13,9 @@ This feature requires the [Microsoft.Testing.Extensions.OpenTelemetry](https://n This extension integrates [OpenTelemetry](https://opentelemetry.io/) with Microsoft.Testing.Platform (MTP), allowing test runs to emit traces and metrics through the standard OpenTelemetry SDK. +> [!NOTE] +> This extension is available in MTP starting with version 2.1.0. + > [!IMPORTANT] > This extension is currently experimental. All public APIs are gated behind the `TPEXP` diagnostic ID. diff --git a/docs/core/testing/microsoft-testing-platform-run-and-debug.md b/docs/core/testing/microsoft-testing-platform-run-and-debug.md index c1ce9b5610594..5ad3bfd3f91a0 100644 --- a/docs/core/testing/microsoft-testing-platform-run-and-debug.md +++ b/docs/core/testing/microsoft-testing-platform-run-and-debug.md @@ -3,7 +3,7 @@ title: Run and debug tests with Microsoft.Testing.Platform (MTP) description: Learn how to run and debug MTP test projects from CLI, Visual Studio, Visual Studio Code, and CI pipelines. author: Evangelink ms.author: amauryleve -ms.date: 02/24/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -23,6 +23,11 @@ MTP test projects are built as executables that can be run (or debugged) directl > [!IMPORTANT] > By default, MTP collects telemetry. For more information and options on opting out, see [MTP telemetry](microsoft-testing-platform-telemetry.md). +> [!NOTE] +> Available in MTP starting with version 2.3.0. +> +> For a graceful stop, press Ctrl+C once to request cancellation. Running tests can finish teardown. To terminate immediately, press Ctrl+C again. + ## [.NET CLI](#tab/dotnetcli) Publishing the test project using `dotnet publish` and running the app directly is another way to run your tests. For example, executing the `./Contoso.MyTests.exe`. In some scenarios it's also viable to use `dotnet build` to produce the executable, but there can be edge cases to consider, such [Native AOT](../deploying/native-aot/index.md). diff --git a/docs/core/testing/microsoft-testing-platform-terminal-output.md b/docs/core/testing/microsoft-testing-platform-terminal-output.md index 83a78d95ab0f0..ae07042ab86c4 100644 --- a/docs/core/testing/microsoft-testing-platform-terminal-output.md +++ b/docs/core/testing/microsoft-testing-platform-terminal-output.md @@ -3,7 +3,7 @@ title: Microsoft.Testing.Platform (MTP) terminal output description: Learn about the built-in terminal test reporter in MTP, including output modes, ANSI support, and progress indicators. author: evangelink ms.author: amauryleve -ms.date: 06/01/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -45,9 +45,13 @@ The progress bar is written based on the selected mode: | Option | Description | |---|---| -| `--no-progress` | Disables reporting progress to screen. | +| `--no-progress` | Disables reporting progress to screen. Deprecated in MTP 2.3.0 in favor of `--progress off`. | +| `--progress` | Controls whether progress is shown. Valid values are `auto` (default), `on` (also accepts `true`, `enable`, `1`), and `off` (also accepts `false`, `disable`, `0`). Available in MTP starting with version 2.3.0. | | `--no-ansi` | Disables outputting ANSI escape characters to screen. | | `--ansi` | Controls whether ANSI escape characters are emitted. Valid values are `auto` (default), `on` (also accepts `true`, `enable`, `1`), and `off` (also accepts `false`, `disable`, `0`). Available in MTP starting with version 2.3.0. | | `--output` | Specifies the output verbosity when reporting tests. Valid values are `Normal` and `Detailed`. Default is `Normal`. | | `--show-stdout` | Determines when to show captured standard output of a test. Valid values are `All`, `Failed`, and `None`. Default is `All`. Available in MTP starting with version 2.2.1. | | `--show-stderr` | Determines when to show captured error output of a test. Valid values are `All`, `Failed`, and `None`. Default is `All`. Available in MTP starting with version 2.2.1. | + +> [!NOTE] +> Starting with MTP 2.3.0, when MTP detects that it runs inside an LLM or AI tool environment, it suppresses the startup banner and changes the default of `--show-stdout` and `--show-stderr` from `All` to `Failed` to reduce noise. diff --git a/docs/core/testing/microsoft-testing-platform-test-reports.md b/docs/core/testing/microsoft-testing-platform-test-reports.md index 210d8263f4a14..a3ae65ed39d27 100644 --- a/docs/core/testing/microsoft-testing-platform-test-reports.md +++ b/docs/core/testing/microsoft-testing-platform-test-reports.md @@ -1,9 +1,9 @@ --- title: Microsoft.Testing.Platform (MTP) test reports -description: Learn about the MTP extensions for generating test report files (TRX, Azure DevOps). +description: Learn about the MTP extensions that create test report files (TRX, HTML, JUnit, CTRF, Azure DevOps). author: evangelink ms.author: amauryleve -ms.date: 06/01/2026 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -14,6 +14,26 @@ These features require installing additional NuGet packages, as described in eac > [!TIP] > When using [Microsoft.Testing.Platform.MSBuild](https://www.nuget.org/packages/Microsoft.Testing.Platform.MSBuild) (included transitively by MSTest, NUnit, and xUnit runners), these extensions are auto-registered when you install their NuGet packages — no code changes needed. The manual registration specified in this article is only required if you disabled the auto-generated entry point by setting `false`. +## Report file names + +Every report extension writes its file to the test results directory, which you can set with the [`--results-directory`](microsoft-testing-platform-cli-options.md) option. To override the name, use the matching `--report-*-filename` option. Each report section lists the default name for that report. + +A file name can include a relative path that stays within the test results directory, and it can use the following replacement items (placeholders): + +| Placeholder | Description | +|---|---| +| `{asm}` | Entry assembly name, or `unknown` when it's unavailable. | +| `{tfm}` | Target framework moniker detected at runtime, such as `net9.0`. | +| `{arch}` | Process architecture, such as `x64`, `x86`, or `arm64`. | +| `{pname}` | Process name. | +| `{pid}` | Process ID. | +| `{time}` | High-precision timestamp. | + +For example, `--report-trx-filename "{asm}_{tfm}_{arch}.trx"` reproduces the default TRX name. + +> [!NOTE] +> Placeholder names are case-sensitive and use lowercase. Placeholder support for report file names is available in MTP starting with version 2.3.0. + ## Visual Studio test reports (TRX) The Visual Studio test result file (or TRX) is the default format for publishing test results. This extension requires the [Microsoft.Testing.Extensions.TrxReport](https://nuget.org/packages/Microsoft.Testing.Extensions.TrxReport) NuGet package. @@ -28,15 +48,84 @@ builder.AddTrxReportProvider(); > [!NOTE] > When using manual registration, register the TRX report provider last. The current implementation depends on registration order, so registering it after all other extensions ensures it captures all test data. +> [!NOTE] +> Available in MTP starting with version 1.9.0, the TRX report includes the test `Description` field. + +> [!NOTE] +> Available in MTP starting with version 2.3.0, TRX results stream to disk as the run progresses. If the test host crashes, the TRX file keeps the results collected before the crash. + ### Options | Option | Description | |---|---| | `--report-trx` | Generates the TRX report. | -| `--report-trx-filename` | The name of the generated TRX report. The default name matches the following format `__.trx`. | +| `--report-trx-filename` | The name of the generated TRX report. Starting with MTP 2.3.0, the default is the deterministic `{asm}_{tfm}_{arch}.trx` form; before MTP 2.3.0, the default was `__.trx`. To customize the name, see [Report file names](#report-file-names). | The report is saved inside the default _TestResults_ folder that can be specified through the `--results-directory` command line argument. +## HTML reports + +The HTML report creates an interactive, self-contained HTML file for a test session. This extension requires the [Microsoft.Testing.Extensions.HtmlReport](https://nuget.org/packages/Microsoft.Testing.Extensions.HtmlReport) NuGet package. + +> [!NOTE] +> Available in MTP starting with version 2.3.0. This extension is experimental, and its options and output format might change in a future version. + +### Manual registration + +```csharp +var builder = await TestApplication.CreateBuilderAsync(args); +builder.AddHtmlReportProvider(); +``` + +### Options + +| Option | Description | +|---|---| +| `--report-html` | Generates the HTML report. | +| `--report-html-filename` | The name of the generated HTML report. The value must end with `.html`. The default is `{asm}_{tfm}_{arch}.html`. To customize the name, see [Report file names](#report-file-names). Requires `--report-html`. | + +## JUnit reports + +The JUnit report creates a JUnit-compatible XML file for a test session. This extension requires the [Microsoft.Testing.Extensions.JUnitReport](https://nuget.org/packages/Microsoft.Testing.Extensions.JUnitReport) NuGet package. + +> [!NOTE] +> Available in MTP starting with version 2.3.0. This extension is experimental, and its options and output format might change in a future version. + +### Manual registration + +```csharp +var builder = await TestApplication.CreateBuilderAsync(args); +builder.AddJUnitReportProvider(); +``` + +### Options + +| Option | Description | +|---|---| +| `--report-junit` | Generates the JUnit XML report. | +| `--report-junit-filename` | The name of the generated JUnit XML report. The value must end with `.xml`. The default is `{asm}_{tfm}_{arch}.xml`. To customize the name, see [Report file names](#report-file-names). Requires `--report-junit`. | + +## CTRF reports + +The CTRF report creates a JSON file that uses the [Common Test Report Format](https://ctrf.io) for a test session. This extension requires the [Microsoft.Testing.Extensions.CtrfReport](https://nuget.org/packages/Microsoft.Testing.Extensions.CtrfReport) NuGet package. + +> [!NOTE] +> Available in MTP starting with version 2.3.0. This extension is experimental, and its options and output format might change in a future version. + +### Manual registration + +```csharp +var builder = await TestApplication.CreateBuilderAsync(args); +builder.AddCtrfReportProvider(); +``` + +### Options + +| Option | Description | +|---|---| +| `--report-ctrf` | Generates the CTRF JSON report. | +| `--report-ctrf-filename` | The name of the generated CTRF JSON report. The value must end with `.json`. The default is `____.ctrf.json`. To customize the name, see [Report file names](#report-file-names). Requires `--report-ctrf`. | + ## Azure DevOps reports Azure DevOps report plugin enhances test running for developers that host their code on GitHub, but build on Azure DevOps build agents. It adds additional information to failures to show failure directly in GitHub PR. @@ -61,6 +150,8 @@ builder.TestHost.AddAzureDevOpsProvider(); | `--report-azdo-flaky-history` | Queries Azure DevOps test result history for the past N days (1-90) and annotates reported failures with flakiness context. Requires `--report-azdo`. | | `--report-azdo-demote-known-flaky` | Demotes failures that are flaky enough in the Azure DevOps history window (default threshold is 25%) from errors to warnings. Requires `--report-azdo` and `--report-azdo-flaky-history`. | | `--report-azdo-quarantine-file` | Path to a text file that lists quarantined test fully qualified names or glob patterns. Matching failures are reported as warnings. Requires `--report-azdo`. | +| `--report-azdo-summary` | Writes a Markdown job summary at the end of the test run and uploads it through `##vso[task.uploadsummary]`. An optional file path argument overrides the default location (`{testResultsDir}/azdo-summary-{tfm}.md`). Requires `--report-azdo`. | +| `--report-azdo-stackframe-filter` | Adds regex patterns, matched against the fully qualified type prefix of each stack frame, that are skipped when the extension locates the user's call site to annotate. The option is repeatable, up to 16 patterns, and each pattern is compiled with a 500-ms match timeout. These patterns are additive to the extension's built-in MSTest assertion-implementation prefixes. Requires `--report-azdo`. | | `--report-azdo-upload-artifacts` | Uploads test result files and/or adds build tags to Azure DevOps. Valid values are `off` (default), `tags-only`, `files`, and `all`. | | `--report-azdo-upload-artifact-include` | Includes files in the Azure DevOps artifact upload using glob patterns relative to the test results directory. Defaults to `**/*`. Requires `--report-azdo-upload-artifacts` to be a value other than `off`. | | `--report-azdo-upload-artifact-exclude` | Excludes files from the Azure DevOps artifact upload using glob patterns relative to the test results directory. Requires `--report-azdo-upload-artifacts` to be a value other than `off`. | @@ -69,6 +160,6 @@ builder.TestHost.AddAzureDevOpsProvider(); | `--publish-azdo-run-name` | Sets a custom Azure DevOps test run name for live test-result publishing. Requires `--publish-azdo-test-results`. | > [!NOTE] -> The Azure DevOps extension became stable in MTP 1.9.0 (`--report-azdo` and `--report-azdo-severity`). All other options in the table — `--report-azdo-flaky-history`, `--report-azdo-demote-known-flaky`, `--report-azdo-quarantine-file`, `--report-azdo-upload-artifacts`, `--report-azdo-upload-artifact-include`, `--report-azdo-upload-artifact-exclude`, `--report-azdo-upload-artifact-name`, `--publish-azdo-test-results`, and `--publish-azdo-run-name` — are available in MTP starting with version 2.3.0. +> The Azure DevOps extension became stable in MTP 1.9.0 (`--report-azdo` and `--report-azdo-severity`). All other options in the table — `--report-azdo-flaky-history`, `--report-azdo-demote-known-flaky`, `--report-azdo-quarantine-file`, `--report-azdo-summary`, `--report-azdo-stackframe-filter`, `--report-azdo-upload-artifacts`, `--report-azdo-upload-artifact-include`, `--report-azdo-upload-artifact-exclude`, `--report-azdo-upload-artifact-name`, `--publish-azdo-test-results`, and `--publish-azdo-run-name` — are available in MTP starting with version 2.3.0. The extension automatically detects that it is running in continuous integration (CI) environment by checking the `TF_BUILD` environment variable. diff --git a/docs/core/testing/mstest-analyzers/mstest0047.md b/docs/core/testing/mstest-analyzers/mstest0047.md new file mode 100644 index 0000000000000..c457b017de210 --- /dev/null +++ b/docs/core/testing/mstest-analyzers/mstest0047.md @@ -0,0 +1,32 @@ +--- +title: "MSTEST0047: Unused TestContext parameter suppressor." +description: "Learn about code suppressor MSTEST0047: Unused TestContext parameter suppressor." +ms.date: 06/16/2026 +ai-usage: ai-assisted +f1_keywords: +- MSTEST0047 +- UnusedParameterSuppressor +helpviewer_keywords: +- UnusedParameterSuppressor +- MSTEST0047 +author: Evangelink +ms.author: amauryleve +--- +# MSTEST0047: Unused TestContext parameter suppressor + +| Property | Value | +|-------------------------------------|-----------------------------------------------------------| +| **Rule ID** | MSTEST0047 | +| **Title** | Suppress IDE0060 for the TestContext parameter | +| **Category** | Suppressor | +| **Introduced in version** | 3.10.0 | + +## Suppressor description + +Suppress the [IDE0060: Remove unused parameter](../../../fundamentals/code-analysis/style-rules/ide0060.md) diagnostic for the parameter of fixture methods. + +MSTest lets you receive the `TestContext` as a parameter of fixture methods that are marked with , , , or . Because the parameter is required by MSTest even when your method body doesn't use it, IDE0060 would otherwise incorrectly flag it as unused. + +## When to disable suppressor + +.NET suppressors cannot be disabled. diff --git a/docs/core/testing/mstest-analyzers/overview.md b/docs/core/testing/mstest-analyzers/overview.md index 6d3ff4c60e02c..76e7c24b5856a 100644 --- a/docs/core/testing/mstest-analyzers/overview.md +++ b/docs/core/testing/mstest-analyzers/overview.md @@ -193,6 +193,7 @@ Rules for properly using the TestContext object: - [MSTEST0005](mstest0005.md) - TestContext should be valid - [MSTEST0024](mstest0024.md) - Do not store static TestContext - [MSTEST0033](mstest0033.md) - Suppress non-nullable reference not initialized warning +- [MSTEST0047](mstest0047.md) - Suppress IDE0060 for the TestContext parameter - [MSTEST0048](mstest0048.md) - TestContext property usage - [MSTEST0049](mstest0049.md) - Flow TestContext CancellationToken - [MSTEST0054](mstest0054.md) - Use CancellationToken property @@ -266,6 +267,7 @@ Related documentation: [Configure MSTest](../unit-testing-mstest-configure.md), | [MSTEST0044](mstest0044.md) | Design | Prefer TestMethod over DataTestMethod | Info | | [MSTEST0045](mstest0045.md) | Design | Use cooperative cancellation for timeout | Info | | [MSTEST0046](mstest0046.md) | Usage | Use Assert instead of StringAssert | Info | +| [MSTEST0047](mstest0047.md) | Suppression | Suppress IDE0060 for the TestContext parameter | N/A | | [MSTEST0048](mstest0048.md) | Usage | TestContext property usage | Warning | | [MSTEST0049](mstest0049.md) | Usage | Flow TestContext CancellationToken | Info | | [MSTEST0050](mstest0050.md) | Usage | Global test fixture should be valid | Warning | diff --git a/docs/core/testing/mstest-analyzers/suppression-rules.md b/docs/core/testing/mstest-analyzers/suppression-rules.md index c6c665ed534ab..9e48d59f66224 100644 --- a/docs/core/testing/mstest-analyzers/suppression-rules.md +++ b/docs/core/testing/mstest-analyzers/suppression-rules.md @@ -17,6 +17,7 @@ Suppression rules automatically suppress diagnostics from other analyzers (like | [MSTEST0027](mstest0027.md) | Suppress async suffix for test methods. | VSTHRD200 | | [MSTEST0028](mstest0028.md) | Suppress async suffix for test fixture methods. | VSTHRD200 | | [MSTEST0033](mstest0033.md) | Suppress non-nullable reference not initialized. | CS8618 | +| [MSTEST0047](mstest0047.md) | Suppress the unused TestContext parameter of fixture methods. | IDE0060 | ## How suppression rules work @@ -62,6 +63,26 @@ public class MyTests } ``` +### IDE0060: Remove unused parameter + +**Suppressed by**: [MSTEST0047](mstest0047.md) + +**Why suppress**: MSTest lets you receive the `TestContext` as a parameter of fixture methods marked with `[AssemblyInitialize]`, `[ClassInitialize]`, `[GlobalTestInitialize]`, or `[GlobalTestCleanup]`. MSTest requires this parameter even when the method body doesn't use it, so IDE0060 (which flags unused parameters) doesn't apply. + +**Example**: + +```csharp +[TestClass] +public class MyTests +{ + [ClassInitialize] + public static void ClassInitialize(TestContext context) // IDE0060 would warn without suppression + { + // context isn't used, but MSTest requires the parameter + } +} +``` + ## Disable suppression rules If you prefer to see these warnings, disable the suppression rules in your `.editorconfig`: @@ -71,6 +92,7 @@ If you prefer to see these warnings, disable the suppression rules in your `.edi dotnet_diagnostic.MSTEST0027.severity = none dotnet_diagnostic.MSTEST0028.severity = none dotnet_diagnostic.MSTEST0033.severity = none +dotnet_diagnostic.MSTEST0047.severity = none ``` ## Related documentation diff --git a/docs/core/testing/unit-testing-mstest-configure.md b/docs/core/testing/unit-testing-mstest-configure.md index 8f8458fce636a..21bb023b285e2 100644 --- a/docs/core/testing/unit-testing-mstest-configure.md +++ b/docs/core/testing/unit-testing-mstest-configure.md @@ -3,7 +3,8 @@ title: Configure MSTest description: Learn how to configure MSTest. author: Evangelink ms.author: amauryleve -ms.date: 04/16/2024 +ms.date: 06/16/2026 +ai-usage: ai-assisted --- # Configure MSTest @@ -35,6 +36,7 @@ The following runsettings entries let you configure how MSTest behaves. |**DeployTestSourceDependencies**|true|A value indicating whether the test source references are to be deployed.| |**EnableBaseClassTestMethodsFromOtherAssemblies**|true|A value indicating whether to enable discovery of test methods from base classes in a different assembly from the inheriting test class.| |**ForcedLegacyMode**|false|In older versions of Visual Studio, the MSTest adapter was optimized to make it faster and more scalable. Some behavior, such as the order in which tests are run, might not be exactly as it was in previous editions of Visual Studio. Set the value to **true** to use the older test adapter.

For example, you might use this setting if you have an *app.config* file specified for a unit test.

We recommend that you consider refactoring your tests to allow you to use the newer adapter.| +|**LaunchDebuggerOnTestFailure**|false|Starting with MSTest 4.2, when set to **true**, MSTest launches the debugger when a test fails.| |**MapInconclusiveToFailed**|false|If a test completes with an inconclusive status, it's mapped to the skipped status in **Test Explorer**. If you want inconclusive tests to be shown as failed, set the value to **true**.| |**MapNotRunnableToFailed**|true|A value indicating whether a not runnable result is mapped to failed test.| |**OrderTestsByNameInClass**|false|If you want to run tests by test names both in Test Explorers and on the command line, set this value to **true**.| @@ -214,6 +216,7 @@ All the settings in this section belong to the `execution` element. | considerEmptyDataSourceAsInconclusive | false | When set to `true`, an empty data source is considered as inconclusive. | | considerFixturesAsSpecialTests | false | To display `AssemblyInitialize`, `AssemblyCleanup`, `ClassInitialize`, `ClassCleanup` as individual entries in Visual Studio and Visual Studio Code `Test Explorer` and _.trx_ log, set this value to **true**. | | mapInconclusiveToFailed | false | If a test completes with an inconclusive status, it's mapped to the skipped status in **Test Explorer**. If you want inconclusive tests to be shown as failed, set the value to **true**. | +| launchDebuggerOnTestFailure | false | Starting with MSTest 4.2, when set to `true`, MSTest launches the debugger when a test fails. | | mapNotRunnableToFailed | true | A value indicating whether a not runnable result is mapped to failed test. | | treatClassAndAssemblyCleanupWarningsAsErrors | false | To see your failures in class cleanups as errors, set this value to **true**. | | treatDiscoveryWarningsAsErrors | false | To report test discovery warnings as errors, set this value to **true**. | diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-assertions.md b/docs/core/testing/unit-testing-mstest-writing-tests-assertions.md index 56db40616c9b2..34b190e65b55d 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-assertions.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-assertions.md @@ -34,6 +34,9 @@ Assert.AreEqual(expected, actual, "Values should match after processing"); Use the class to verify that the code under test behaves as expected. +> [!NOTE] +> Starting with MSTest 4.0, all `Assert` APIs capture the argument expression and include it in failure messages. This support provides richer diagnostics without a manual `message` parameter. + ### Common assertion methods ```csharp @@ -67,6 +70,14 @@ public async Task AssertExamples() } ``` +### The `Assert.That` method + +Starting with MSTest 4.0, `Assert.That` evaluates any Boolean expression and produces a clear failure message. For richer diagnostics, `Assert.That` uses `[CallerArgumentExpression]` to capture the expression text automatically. + +```csharp +Assert.That(order.Total > 0); +``` + ### Available APIs - @@ -79,10 +90,12 @@ public async Task AssertExamples() - - - +- - - - - +- - - - @@ -92,6 +105,7 @@ public async Task AssertExamples() - - - +- - - - @@ -99,11 +113,21 @@ public async Task AssertExamples() - - - +- `Assert.That` - - - - +> [!NOTE] +> Starting with MSTest 3.8, collection assertions include `Assert.Contains`, `Assert.DoesNotContain`, `Assert.HasCount`, `Assert.IsEmpty`, `Assert.IsNotEmpty`, and `Assert.ContainsSingle`. +> +> Starting with MSTest 3.10, comparison assertions include `Assert.IsInRange`, `Assert.IsGreaterThan`, `Assert.IsGreaterThanOrEqualTo`, `Assert.IsLessThan`, `Assert.IsLessThanOrEqualTo`, `Assert.IsPositive`, and `Assert.IsNegative`. +> +> Starting with MSTest 3.10, string-matching assertions include `Assert.StartsWith`, `Assert.EndsWith`, `Assert.MatchesRegex`, `Assert.DoesNotStartWith`, `Assert.DoesNotEndWith`, and `Assert.DoesNotMatchRegex`. +> +> Starting with MSTest 4.1, `Assert.IsExactInstanceOfType` and `Assert.IsNotExactInstanceOfType` require an exact type match. Unlike `Assert.IsInstanceOfType`, these methods don't match derived types. + ### New collection and equivalence assertions in MSTest 4.3 > [!NOTE] diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md b/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md index 9b35cc1f3b88f..b24944390cf7e 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md @@ -3,7 +3,7 @@ title: Test execution and control in MSTest description: Learn how to control test execution in MSTest with parallelization, threading, timeouts, retries, and conditional execution. author: Evangelink ms.author: amauryleve -ms.date: 07/15/2025 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -365,7 +365,7 @@ public class RetryTests ### Custom retry implementations -Create custom retry logic by inheriting from : +Starting with MSTest 3.8, create custom retry logic by inheriting from : ```csharp public class CustomRetryAttribute : RetryBaseAttribute @@ -390,6 +390,9 @@ Conditional execution attributes control whether tests run based on specific con The is the abstract base class for conditional execution. MSTest provides several built-in implementations. +> [!NOTE] +> The `ConditionBaseAttribute` was introduced in MSTest 3.8. + > [!NOTE] > By default, condition attributes aren't inherited. Applying them to a base class doesn't affect derived classes. Custom condition attributes can override this behavior by redefining `AttributeUsage`, but this isn't recommended to maintain consistency with the built-in condition attributes. @@ -402,6 +405,9 @@ The i The runs or skips tests based on the operating system. Use the flags enum to specify which operating systems apply. +> [!NOTE] +> The `OSConditionAttribute` was introduced in MSTest 3.8. + ```csharp [TestClass] public class OSSpecificTests @@ -449,6 +455,9 @@ Combine operating systems with the bitwise OR operator (`|`). The runs or skips tests based on whether they're executing in a continuous integration environment. +> [!NOTE] +> The `CIConditionAttribute` was introduced in MSTest 3.10. + ```csharp [TestClass] public class CIAwareTests diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md b/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md index 568d0d83e56a3..6039045c0dcc8 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md @@ -4,7 +4,7 @@ description: Learn how to use data-driven testing in MSTest with DataRow, Dynami author: Evangelink ms.author: amauryleve ai-usage: ai-assisted -ms.date: 03/09/2026 +ms.date: 06/16/2026 --- # Data-driven testing in MSTest @@ -98,6 +98,9 @@ public class DataRowExamples } ``` +> [!NOTE] +> Starting with MSTest v3.10, use `DateOnly` and `TimeOnly` as `DataRow` arguments and in `DynamicData` parameterized tests. + ### Using params for variable arguments Use the `params` keyword to accept a variable number of arguments: @@ -117,6 +120,20 @@ public class ParamsExample } ``` +### Generic test methods + +Starting with MSTest v3.8, a `TestMethod` can have type parameters. The framework infers type arguments from `DataRow` or `DynamicData` values: + +```csharp +[TestMethod] +[DataRow(42)] +[DataRow("alpha")] +public void Value_RoundTrips(T value) +{ + Assert.AreEqual(value, value); +} +``` + ### Custom display names Set the property to customize how test cases appear in Test Explorer: @@ -178,7 +195,10 @@ The data source can return any `IEnumerable` where `T` is one of the types li ### Data sources -The data source can be a method, property, or field. All three are interchangeable—choose based on your preference: +The data source can be a method or property and, starting with MSTest v3.11, a field. These sources are interchangeable, so choose based on your preference: + +> [!NOTE] +> Starting with MSTest v3.8, `DynamicData` auto-detects the data source type. You don't need to specify `DynamicDataSourceType` explicitly. ```csharp [TestClass] @@ -231,6 +251,9 @@ public class DynamicDataExample > [!NOTE] > Data source methods, properties, and fields must be `public static` and return an `IEnumerable` of a supported type. +> [!NOTE] +> Starting with MSTest v3.11, the data source can be a field. Earlier versions support methods and properties. + > [!TIP] > Related analyzer: [MSTEST0018](mstest-analyzers/mstest0018.md) validates that the data source exists, is accessible, and has the correct signature. @@ -260,6 +283,19 @@ public class DynamicDataExternalExample } ``` +### Parameterized `DynamicData` source methods + +Starting with MSTest v3.10, pass values to a `DynamicData` source method with the `Arguments` property: + +```csharp +[TestMethod] +[DynamicData(nameof(GetValues), Arguments = new object[] { true })] +public void Value_IsPositive(int value, bool expected) => Assert.AreEqual(expected, value > 0); + +public static IEnumerable<(int Value, bool Expected)> GetValues(bool includeZero) => + includeZero ? [(1, true), (0, false)] : [(1, true)]; +``` + ### Custom display names Customize test case display names using the property: @@ -326,6 +362,9 @@ public class IgnoreDynamicDataExample The class provides enhanced control over test data in data-driven tests. Use of as your data source return type to specify: +> [!NOTE] +> MSTest introduced `TestDataRow` in version 3.8. + - **Custom display names**: Set a unique display name per test case using the property. - **Test categories**: Attach metadata to individual test cases using the property. - **Ignore messages**: Skip specific test cases with reasons using the property. diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-lifecycle.md b/docs/core/testing/unit-testing-mstest-writing-tests-lifecycle.md index cda5a692e7fbc..f45d7087980f9 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-lifecycle.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-lifecycle.md @@ -3,7 +3,7 @@ title: MSTest test lifecycle description: Learn about the creation and lifecycle of test classes and test methods in MSTest, including initialization and cleanup at assembly, class, and test levels. author: marcelwgn ms.author: marcelwagner -ms.date: 07/15/2025 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -151,6 +151,9 @@ public class ClassLifecycleExample - `ClassCleanup` accepts zero parameters, or one `TestContext` parameter (MSTest 3.8+) - Only one of each attribute allowed per class +> [!NOTE] +> Starting with MSTest 4.2, MSTest reports failures in `ClassCleanup` and `AssemblyCleanup` as a separate test result. The separate result makes cleanup failures easier to identify in Test Explorer and TRX reports. + ### Inheritance behavior Control whether `ClassInitialize` runs for derived classes using : diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-organizing.md b/docs/core/testing/unit-testing-mstest-writing-tests-organizing.md index 1de4fb210f206..db58b232371fe 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-organizing.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-organizing.md @@ -3,7 +3,8 @@ title: Test organization and metadata in MSTest description: Learn how to organize and categorize tests in MSTest using categories, properties, priorities, owners, and work item references. author: Evangelink ms.author: amauryleve -ms.date: 07/15/2025 +ms.date: 06/16/2026 +ai-usage: ai-assisted --- # Test organization and metadata in MSTest @@ -288,6 +289,9 @@ public class BugFixTests The links tests to GitHub issues. +> [!NOTE] +> The `GitHubWorkItemAttribute` was introduced in MSTest 3.8. + ```csharp [TestClass] public class GitHubLinkedTests diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-testcontext.md b/docs/core/testing/unit-testing-mstest-writing-tests-testcontext.md index fb3a61c551ebf..297c723997a3e 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-testcontext.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-testcontext.md @@ -3,7 +3,7 @@ title: MSTest TestContext description: Learn about the TestContext class of MSTest. author: Evangelink ms.author: amauryleve -ms.date: 11/12/2024 +ms.date: 06/16/2026 ai-usage: ai-assisted --- @@ -42,6 +42,7 @@ The provides inf - - the directory where the test results are stored. Typically a subdirectory of the . - - the directory where the test results are stored. Typically a subdirectory of the . - - the directory where the test results are stored. Typically a subdirectory of the . +- Starting with MSTest 3.9, - the number of times the current test has run, counting from 1. The value is greater than 1 when a test is retried with `[Retry]`. In MSTest 3.7 and later, the class also provides new properties helpful for `TestInitialize` and `TestCleanup` methods: @@ -78,8 +79,14 @@ string value = TestContext.Properties["MyKey"]?.ToString(); ``` > [!NOTE] +> Starting with MSTest 4.2, test categories from `[TestCategory]` are included in . +> > Starting with MSTest 4.3, custom properties added to `TestContext.Properties` in `[AssemblyInitialize]` flow to every class and test in the assembly, and properties added in `[ClassInitialize]` flow to every test in that class. This lets fixtures publish shared context that test methods can read. +### Access `TestContext` from the current call stack + +Starting with MSTest 4.2, returns the current test's from anywhere in the call stack during test method execution. This API is experimental, uses the `[Experimental]` attribute, and might change in a future MSTest version. + ### Associate data to a test The method allows you to add a file to the test results, making it available for review in the test output. This can be useful if you generate files during your test (for example, log files, screenshots, or data files) that you want to attach to the test results. diff --git a/docs/navigate/devops-testing/toc.yml b/docs/navigate/devops-testing/toc.yml index 082e426a1b0d4..4576cbe075a1a 100644 --- a/docs/navigate/devops-testing/toc.yml +++ b/docs/navigate/devops-testing/toc.yml @@ -130,6 +130,8 @@ items: href: ../../core/testing/mstest-analyzers/mstest0028.md - name: MSTEST0033 href: ../../core/testing/mstest-analyzers/mstest0033.md + - name: MSTEST0047 + href: ../../core/testing/mstest-analyzers/mstest0047.md - name: Usage rules items: - name: Overview From 124769557d5b772f67420f9576af066eaf2acda3 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 7 Jul 2026 14:08:05 -0400 Subject: [PATCH 03/26] Add exploration tutorial for unions and closed hierarchies (#54627) * First draft of these tutorials * Use a better generic sample * Review articles. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update sample and code. * Fix preview build errors You might need to add a polyfill * Fix snippet name * Apply suggestions from code review Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com> * Respond to feedback. Updates based on remaining feedback. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com> --- docs/csharp/toc.yml | 4 + .../whats-new/tutorials/closed-hierarchies.md | 148 ++++++++++++++++ .../SmartHome.App/Program.cs | 63 +++++++ .../SmartHome.App/SmartHome.App.csproj | 16 ++ .../SmartHome.Core/ClosedPolyfill.cs | 4 + .../SmartHome.Core/Quantity.cs | 45 +++++ .../SmartHome.Core/Readings.cs | 22 +++ .../SmartHome.Core/Report.cs | 21 +++ .../SmartHome.Core/Result.cs | 39 +++++ .../SmartHome.Core/Sample.cs | 34 ++++ .../SmartHome.Core/Sensors.cs | 27 +++ .../SmartHome.Core/SmartHome.Core.csproj | 10 ++ .../SmartHome.Core/UnionSupport.cs | 21 +++ .../SmartHome.Extensions/DoorContact.cs | 11 ++ .../SmartHome.Extensions.csproj | 14 ++ docs/csharp/whats-new/tutorials/unions.md | 163 ++++++++++++++++++ 16 files changed, 642 insertions(+) create mode 100644 docs/csharp/whats-new/tutorials/closed-hierarchies.md create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/Program.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/SmartHome.App.csproj create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/ClosedPolyfill.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Quantity.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Readings.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Report.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sample.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sensors.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/SmartHome.Core.csproj create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/UnionSupport.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/DoorContact.cs create mode 100644 docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/SmartHome.Extensions.csproj create mode 100644 docs/csharp/whats-new/tutorials/unions.md diff --git a/docs/csharp/toc.yml b/docs/csharp/toc.yml index 32ef47e296010..92b994442b625 100644 --- a/docs/csharp/toc.yml +++ b/docs/csharp/toc.yml @@ -233,6 +233,10 @@ items: href: whats-new/version-update-considerations.md - name: Tutorials items: + - name: Explore union types + href: whats-new/tutorials/unions.md + - name: Explore closed hierarchies + href: whats-new/tutorials/closed-hierarchies.md - name: Explore extension members href: whats-new/tutorials/extension-members.md - name: Explore compound assignment diff --git a/docs/csharp/whats-new/tutorials/closed-hierarchies.md b/docs/csharp/whats-new/tutorials/closed-hierarchies.md new file mode 100644 index 0000000000000..ae76e678cafa2 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/closed-hierarchies.md @@ -0,0 +1,148 @@ +--- +title: Explore closed hierarchies in C# +description: "A closed hierarchy restricts a base type's direct subtypes to one assembly so the compiler can verify exhaustive matches. Learn to declare closed hierarchies, decide what to seal, and use them with generics." +author: billwagner +ms.author: wiwagn +ms.service: dotnet-csharp +ms.topic: tutorial +ms.date: 07/03/2026 +ai-usage: ai-assisted +#customer intent: As a C# developer, I model a fixed set of related types so the compiler enforces that I handle every subtype. +--- +# Tutorial: Explore C# closed hierarchies + +A *closed hierarchy* restricts the direct subtypes of a base type to the assembly that declares it. Because the compiler knows the full set of subtypes, it can verify that a `switch` expression is exhaustive without a default arm. Closed hierarchies suit domains where the set of cases is stable and you want the compiler to flag every place that needs to change when you add a case. + +In this tutorial, you build the sensor model of a smart-home telemetry monitor. You declare a closed hierarchy of sensor types, match the sensors exhaustively, and decide which cases to seal and which to leave open for extension. + +In this tutorial, you: + +> [!div class="checklist"] +> +> * Declare a closed hierarchy and match its cases exhaustively. +> * Decide which subtypes to seal and which to leave open. +> * Extend an open case from another assembly. +> * Use a closed hierarchy with generics. + +## Prerequisites + +This tutorial uses preview language features. You need an SDK that supports closed hierarchies and a language version set to `preview`. To get started, you'll need: + +- The .NET 11 SDK preview 5 SDK or a later version. Download it from the [.NET download site](https://dotnet.microsoft.com/download/dotnet). +- An editor such as Visual Studio or Visual Studio Code with the C# Dev Kit. + +> [!IMPORTANT] +> Closed hierarchies are a preview feature. The syntax and behavior can change before the feature ships. Set `preview` in your project to enable it. + +## Create the sample solution + +You build a class library, `SmartHome.Core`, that holds the closed hierarchy, a second library, `SmartHome.Extensions`, that extends an open case, and a console app, `SmartHome.App`, that drives them. + +1. Open a terminal and run the following `dotnet` commands from a new folder previously created to store the code for tutorial: + + ```dotnetcli + dotnet new sln -n TelemetryMonitor + dotnet new classlib --langversion preview -n SmartHome.Core + dotnet new classlib --langversion preview -n SmartHome.Extensions + dotnet new console --langversion preview -n SmartHome.App + dotnet sln add SmartHome.Core SmartHome.Extensions SmartHome.App + dotnet add SmartHome.Extensions reference SmartHome.Core + dotnet add SmartHome.App reference SmartHome.Core SmartHome.Extensions + ``` + +1. The previous commands included the `--langversion preview` to enable C# 15 preview features. In each project file, verify that the language version is set to `preview`: + + ```xml + + preview + + ``` + +## Declare a closed hierarchy + +Start with the sensor model. The monitor supports a fixed set of sensor kinds, so you model them as a closed hierarchy in a single assembly. + +1. In `SmartHome.Core`, add a file named `Sensors.cs` and declare the `Sensor` base type with the `closed` modifier and its three derived types: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Sensors.cs" id="ClosedSensor"::: + +1. In the same file, add a method that matches every sensor with a switch expression: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Sensors.cs" id="SensorExhaustive"::: + +1. Build the project. .NET 11 preview 5 has the language support for closed hierarchies, but a necessary type won't be added until a later preview. If you get build errors, you need to add a polyfill for the `Closed` attribute. Add the following code to the `SmartHome.Core` project in a file named `ClosedPolyfill.cs`: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/ClosedPolyfill.cs"::: + +The `closed` modifier restricts the direct subtypes of `Sensor` to the declaring assembly, and a `closed` type is implicitly abstract, so you can't instantiate it directly. Because the compiler knows the complete set of subtypes, the switch needs no default arm. If you add a new sensor type later, the compiler reports that this switch no longer covers every case. That feedback is the central benefit of a closed hierarchy. The compiler points you to every match that needs to change. The `Temperature` and `Humidity` cases are sealed because their shape is final, while `Contact` stays open as an extension point that the next section covers. For more information, see the [`closed` modifier](../../language-reference/keywords/closed.md) and [Closed hierarchy patterns](../../language-reference/operators/patterns.md#closed-hierarchy-patterns). + +## Decide what to seal + +A subtype of a closed type isn't itself closed unless you declare it so. For each subtype, you have three choices: + +- Mark it `closed` to continue the hierarchy: further subtypes are allowed, but only in the same assembly. +- Mark it `sealed` to end the hierarchy: no further subtypes are allowed anywhere. +- Leave it unmarked to make it open: other assemblies can derive from it, and those derived types still match the original case. + +You left `Contact` unmarked for that reason, so now you extend it from another assembly. + +1. In `SmartHome.Extensions`, add a file named `DoorContact.cs` that derives from the open `Contact` case: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Extensions/DoorContact.cs" id="DoorContact"::: + +1. In `SmartHome.App`, add code that matches a `DoorContact` through the existing `Sensor` switch: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.App/Program.cs" id="DoorContactConsume"::: + +A `DoorContact` can't derive from `Sensor` directly, because it's closed to other assemblies. `DoorContact` extends the open `Contact` leaf instead. A `DoorContact` still matches the `Contact` case, so the exhaustive switch over `Sensor` stays correct without any change. When you choose what to seal, weigh the trade-off: seal a case to lock its shape and keep the hierarchy fully known, or leave a case open to allow extension at the cost of a less precise match, because the switch sees the open base case rather than the derived type. For more information, see the [`closed` modifier](../../language-reference/keywords/closed.md). + +## Use a closed hierarchy with generics + +A closed hierarchy can be generic. A report from the monitor is either a single value or a group of nested reports, so model it as a generic closed hierarchy. + +1. In `SmartHome.Core`, add a file named `Report.cs` and declare the closed `Report` base with its two cases. A derived type can't introduce a type parameter that the base type doesn't have, but it can supply fixed arguments for one or more of the base type's type parameters: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Report.cs" id="ClosedReport"::: + +1. Add a recursive method that accumulates the report by switching over its cases: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Report.cs" id="ReportFold"::: + +The switch over `Single` and `Group` is exhaustive because `Report` is closed, so the recursive accumulator needs no default arm. For more information, see [Closed hierarchy patterns](../../language-reference/operators/patterns.md#closed-hierarchy-patterns). + +## Run the sample + +The console app builds each sensor and report, then prints them through the exhaustive switches. Open `Program.cs` and add the following code: + +:::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.App/Program.cs" id="ClosedMain"::: + +Then, run the app: + +```dotnetcli +dotnet run --project SmartHome.App +``` + +The sensors and report print through their exhaustive switches: + +```output +Sensor: 21.4°C +Sensor: 55% RH +Sensor: open +Sensor: closed +Report leaves: 3 +``` + +## Summary + +You built the sensor model of a smart-home telemetry monitor and, in the process, worked through closed-hierarchy scenarios. You: + +- Declared a `closed Sensor` base type and matched its subtypes with an exhaustive switch that needs no default arm. +- Weighed the three choices for each subtype: `closed` to continue the hierarchy in the same assembly, `sealed` to end it, or unmarked to leave an extension point. +- Extended the open `Contact` case from a separate assembly with `DoorContact`, and confirmed it still matches the `Contact` case in the existing switch. +- Declared a generic closed hierarchy, `Report`, and folded it with a recursive exhaustive switch. + +## Related content + +- [Union types tutorial](unions.md) +- [Pattern matching overview](../../fundamentals/functional/pattern-matching.md) +- [What's new in C# 15](../csharp-15.md) diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/Program.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/Program.cs new file mode 100644 index 0000000000000..2a513f74b11d0 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/Program.cs @@ -0,0 +1,63 @@ +using SmartHome.Core; +using SmartHome.Extensions; + +UnionMain(); +ClosedMain(); + +void UnionMain() +{ + // + // Union declarations: a Reading holds a double, bool, or string. + Reading[] readings = [23.5, true, "offline"]; + foreach (Reading reading in readings) + { + Console.WriteLine($"Reading: {ReadingReporter.Render(reading)}"); + } + Console.WriteLine($"Reading: {ReadingReporter.Render(default)}"); + + // Migrate from a conventional result type to a union. + Result ok = 42.0; + Result bad = new TimeoutException("sensor timed out"); + Console.WriteLine(ResultReporter.Describe(ok)); + Console.WriteLine(ResultReporter.Describe(bad)); + + // Generic union reused across numeric widths. + Sample raw = (byte)200; + Sample railed = new Saturated(High: true); + Console.WriteLine($"Sample: {SampleReporter.Normalize(raw, byte.MaxValue):P0} (in range: {raw.InRange})"); + Console.WriteLine($"Sample: {SampleReporter.Normalize(railed, short.MaxValue):P0} (in range: {railed.InRange})"); + + // Custom non-boxing union. + Console.WriteLine(QuantityReporter.Describe(new Quantity(3))); + Console.WriteLine(QuantityReporter.Describe(new Quantity(2.5))); + // +} + +void ClosedMain() +{ + // + // Closed hierarchy with an exhaustive switch. + Sensor[] sensors = + [ + new Temperature(21.4), + new Humidity(55), + new Contact(Open: true), + ]; + foreach (Sensor sensor in sensors) + { + Console.WriteLine($"Sensor: {SensorReporter.Describe(sensor)}"); + } + + // + // A DoorContact from another assembly still matches the Contact case. + Sensor frontDoor = new DoorContact(Open: false, Door: "Front"); + Console.WriteLine($"Sensor: {SensorReporter.Describe(frontDoor)}"); + // + + // Generic closed hierarchy. + Report report = new Group( + new Single("Kitchen"), + new Group(new Single("Garage"), new Single("Attic"))); + Console.WriteLine($"Report leaves: {ReportReporter.Count(report)}"); + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/SmartHome.App.csproj b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/SmartHome.App.csproj new file mode 100644 index 0000000000000..6b21776a405c3 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.App/SmartHome.App.csproj @@ -0,0 +1,16 @@ + + + + + + + + + Exe + net10.0 + enable + enable + preview + + + diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/ClosedPolyfill.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/ClosedPolyfill.cs new file mode 100644 index 0000000000000..229927f42009d --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/ClosedPolyfill.cs @@ -0,0 +1,4 @@ +namespace System.Runtime.CompilerServices; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] +public sealed class ClosedAttribute : Attribute { } diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Quantity.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Quantity.cs new file mode 100644 index 0000000000000..02fdee4591b67 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Quantity.cs @@ -0,0 +1,45 @@ +using System.Runtime.CompilerServices; + +namespace SmartHome.Core; + +// +// A custom union type. The 'union' shorthand boxes value-type cases, so a +// performance-sensitive type can implement the union pattern by hand to store +// the value without boxing. The [Union] attribute opts the struct into union +// behaviors; the non-boxing access members (HasValue and TryGetValue) let the +// compiler match each case without boxing. +[Union] +public readonly struct Quantity : IUnion +{ + private readonly double _value; + private readonly bool _isCount; + + public Quantity(int count) => (_value, _isCount) = (count, true); + public Quantity(double measure) => (_value, _isCount) = (measure, false); + + public object? Value => _isCount ? (int)_value : _value; + + public bool HasValue => true; + public bool TryGetValue(out int value) + { + value = (int)_value; + return _isCount; + } + public bool TryGetValue(out double value) + { + value = _value; + return !_isCount; + } +} +// + +public static class QuantityReporter +{ + // + public static string Describe(Quantity quantity) => quantity switch + { + int count => $"{count} items", + double measure => $"{measure:F2} units", + }; + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Readings.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Readings.cs new file mode 100644 index 0000000000000..3ac3e62ae6d2d --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Readings.cs @@ -0,0 +1,22 @@ +namespace SmartHome.Core; + +// +// A union declaration is shorthand for a struct that holds one of the listed +// case types. The 'string?' case makes the contents nullable. +public union Reading(double, bool, string?); +// + +public static class ReadingReporter +{ + // + public static string Render(Reading reading) => reading switch + { + // Each type pattern applies to the union's contents, not to the Reading value. + double measure => $"{measure:F1}", + bool isOn => isOn ? "on" : "off", + string text => text, + // The contents can be null because 'string?' is a nullable case type. + null => "no reading", + }; + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Report.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Report.cs new file mode 100644 index 0000000000000..36366bb61acd8 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Report.cs @@ -0,0 +1,21 @@ +namespace SmartHome.Core; + +// +// A generic closed hierarchy. Every type parameter of a derived type must appear +// in the base type, so a single derived construction exhausts each Report. +public closed record class Report; +public sealed record class Single(T Value) : Report; +public sealed record class Group(Report Left, Report Right) : Report; +// + +public static class ReportReporter +{ + // + public static int Count(Report report) => report switch + { + Single => 1, + Group group => Count(group.Left) + Count(group.Right), + // Exhaustive: Report is closed and both subtypes are handled. + }; + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs new file mode 100644 index 0000000000000..8f2ac6c5fcbaa --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs @@ -0,0 +1,39 @@ +namespace SmartHome.Core; + +// +// A conventional result type. Callers must remember to check 'IsSuccess' before +// they read 'Value', and nothing stops them from reading the wrong field. +public sealed class QueryResult +{ + private QueryResult(bool isSuccess, T? value, Exception? error) + { + IsSuccess = isSuccess; + Value = value; + Error = error; + } + + public bool IsSuccess { get; } + public T? Value { get; } + public Exception? Error { get; } + + public static QueryResult Success(T value) => new(true, value, null); + public static QueryResult Failure(Exception error) => new(false, default, error); +} +// + +// +// The same idea as a union declaration. A Result holds either a T or an Exception. +public union Result(T, Exception); +// + +public static class ResultReporter +{ + // + public static string Describe(Result result) => result switch + { + T value => $"Success: {value}", + Exception error => $"Failure: {error.Message}", + null => "Failure: no value", + }; + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sample.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sample.cs new file mode 100644 index 0000000000000..a43ceb8795444 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sample.cs @@ -0,0 +1,34 @@ +using System.Numerics; + +namespace SmartHome.Core; + +// +// A generic union, reusable across sensors of different numeric precision. A +// Sample holds either an in-range reading of type T or a Saturated marker +// for a sensor that railed. The 'struct, INumber' constraint keeps T a +// non-nullable numeric value type, so a switch over the cases needs no null arm. +public union Sample(T, Saturated) where T : struct, INumber +{ + // A union can declare members. This property patterns over 'this' to report + // whether the sample carries a usable reading. + public bool InRange => this is T; +} + +// A marker for a railed sensor, carrying which rail it hit. +public readonly record struct Saturated(bool High); +// + +public static class SampleReporter +{ + // + // Scale any numeric width to a fraction of full scale. The INumber + // constraint makes the same arithmetic work for byte, short, int, and more. + public static double Normalize(Sample sample, T fullScale) + where T : struct, INumber => sample switch + { + T value => double.CreateChecked(value) / double.CreateChecked(fullScale), + Saturated { High: true } => 1.0, + Saturated => 0.0, + }; + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sensors.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sensors.cs new file mode 100644 index 0000000000000..a98a2dbf7cb4d --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/Sensors.cs @@ -0,0 +1,27 @@ +namespace SmartHome.Core; + +// +// A closed class restricts its direct subtypes to this assembly. A 'closed' +// class is implicitly abstract. +public closed record class Sensor; + +// Seal the cases whose shape is final. +public sealed record class Temperature(double Celsius) : Sensor; +public sealed record class Humidity(double Percent) : Sensor; + +// Leave a case unsealed as an "escape hatch" so other assemblies can specialize it. +public record class Contact(bool Open) : Sensor; +// + +public static class SensorReporter +{ + // + public static string Describe(Sensor sensor) => sensor switch + { + Temperature temperature => $"{temperature.Celsius:F1}°C", + Humidity humidity => $"{humidity.Percent:F0}% RH", + Contact contact => contact.Open ? "open" : "closed", + // No default arm is needed. Sensor is closed, so these cases are exhaustive. + }; + // +} diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/SmartHome.Core.csproj b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/SmartHome.Core.csproj new file mode 100644 index 0000000000000..39b1711893882 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/SmartHome.Core.csproj @@ -0,0 +1,10 @@ + + + + net10.0 + enable + enable + preview + + + diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/UnionSupport.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/UnionSupport.cs new file mode 100644 index 0000000000000..f735dbc2c28eb --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Core/UnionSupport.cs @@ -0,0 +1,21 @@ +// TEMPORARY SHIM. +// +// The unions and closed-hierarchy features rely on these support types. A later +// .NET SDK ships them in the base class library, at which point this file should +// be deleted. They're defined here so the sample compiles on the preview SDK that +// recognizes the language syntax but doesn't yet include the types. +// +// This file is intentionally NOT referenced by any tutorial snippet. + +namespace System.Runtime.CompilerServices; + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] +public class UnionAttribute : Attribute; + +public interface IUnion +{ + object? Value { get; } +} + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] +public sealed class IsClosedTypeAttribute : Attribute; diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/DoorContact.cs b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/DoorContact.cs new file mode 100644 index 0000000000000..05a5eba6b097d --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/DoorContact.cs @@ -0,0 +1,11 @@ +using SmartHome.Core; + +namespace SmartHome.Extensions; + +// +// This type lives in a different assembly than the closed Sensor hierarchy. +// It can't derive from Sensor directly, but it can extend the unsealed Contact +// leaf. A DoorContact still matches the 'Contact' case, so switches over Sensor +// stay exhaustive. +public sealed record class DoorContact(bool Open, string Door) : Contact(Open); +// diff --git a/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/SmartHome.Extensions.csproj b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/SmartHome.Extensions.csproj new file mode 100644 index 0000000000000..d3227e65cc5e2 --- /dev/null +++ b/docs/csharp/whats-new/tutorials/snippets/shared/telemetry-monitor/SmartHome.Extensions/SmartHome.Extensions.csproj @@ -0,0 +1,14 @@ + + + + + + + + net10.0 + enable + enable + preview + + + diff --git a/docs/csharp/whats-new/tutorials/unions.md b/docs/csharp/whats-new/tutorials/unions.md new file mode 100644 index 0000000000000..82ffeec1f6fec --- /dev/null +++ b/docs/csharp/whats-new/tutorials/unions.md @@ -0,0 +1,163 @@ +--- +title: Explore union types in C# +description: "Union types let a single value hold one of a fixed set of types. Learn to declare union types, match their cases exhaustively, build custom unions, and use them with generics." +author: billwagner +ms.author: wiwagn +ms.service: dotnet-csharp +ms.topic: tutorial +ms.date: 07/02/2026 +ai-usage: ai-assisted +#customer intent: As a C# developer, I model a value that can be one of several types so the compiler enforces that I handle every case. +--- +# Tutorial: Explore C# union types + +A *union type* holds a single value that's one of a fixed set of types. Those types typically aren't related by inheritance, so a union lets you group unrelated types without forcing them into a common base class or interface. Unions are useful when a value is conceptually "one of these," such as a sensor reading that's a number, a switch state, or a status message. Because the set of cases is fixed, the compiler can verify that you handle every case when you read the value. + +In this tutorial, you build the readings layer of a smart-home telemetry monitor. You declare union types for sensor data, replace a hand-rolled result type with a union, and create a custom union for performance-sensitive code. + +In this tutorial, you: + +> [!div class="checklist"] +> +> * Declare union types and match their cases exhaustively. +> * Handle null contents in a union. +> * Add members and use generics with union declarations. +> * Build a custom union type that avoids boxing. + +## Prerequisites + +This tutorial uses preview language features. You need an SDK that supports closed hierarchies and a language version set to `preview`. To get started, you'll need: + +- The .NET 11 SDK preview 5 SDK or a later version. Download it from the [.NET download site](https://dotnet.microsoft.com/download/dotnet). +- An editor such as Visual Studio or Visual Studio Code with the C# Dev Kit. + +> [!IMPORTANT] +> Union types are a preview feature. The syntax and supporting types can change before the feature ships. Set `preview` in your project to enable it. + +## Create the sample solution + +You build a class library, `SmartHome.Core`, that holds the union types, and a console app, `SmartHome.App`, that exercises them. + +1. Create the solution and projects: + + ```dotnetcli + dotnet new sln -n TelemetryMonitor + dotnet new classlib --langversion preview -n SmartHome.Core + dotnet new console --langversion preview -n SmartHome.App + dotnet sln add SmartHome.Core SmartHome.App + dotnet add SmartHome.App reference SmartHome.Core + ``` + +1. The previous commands included the `--langversion preview` to enable C# 15 preview features. In each project file, verify that the language version is set to `preview`: + + ```xml + + preview + + ``` + +## Declare a union type + +Start with the raw sensor data. A reading arrives as a number, a switch state, or a status message, so you model it as a union of those three types. + +1. In `SmartHome.Core`, add a file named `Readings.cs` and declare the `Reading` union. A *union declaration* lists the case types in parentheses: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Readings.cs" id="ReadingUnion"::: + +1. In the same file, add a method that reads a `Reading` by switching over its case types: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Readings.cs" id="ReadingConsume"::: + +Each type pattern applies to the union's *contents*, not to the `Reading` instance, because most patterns unwrap the union. The `string?` case is nullable, so the compiler treats null as a distinct case and requires the `null` arm. The switch is exhaustive: if you remove any arm, the compiler reports that a case isn't covered. That guarantee is one benefit of a union. When you add a case type later, every switch that reads the union flags the missing arm. For more information, see [Union exhaustiveness](../../language-reference/builtin-types/union.md#union-exhaustiveness) and [Union patterns](../../language-reference/operators/patterns.md#union-patterns). + +## Migrate a result type to a generic union + +When a sensor read can fail, you need a type that carries either a value or an error. Many codebases model that type with a class that exposes a success flag and two fields. Replace that class with a generic union. + +1. In `SmartHome.Core`, add a file named `Result.cs` with the hand-rolled result class that the migration replaces: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs" id="ResultBefore"::: + +1. Replace that class with a generic union. A `Result` holds either a `T` or an `Exception`: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs" id="ResultUnion"::: + +1. Add a method that reads the result by switching over its case types: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Result.cs" id="ResultConsume"::: + +The original class lets a caller incorrectly read `Value` on a failure or `Error` on a success. The union removes those invalid states: a `Result` is either a `T` that holds the successful result or an `Exception` that explains why the operation failed. Each case converts to the union implicitly, so you assign an instance of `T` or an instance of `Exception` directly to a `Result`. When you read the result, a switch verifies that you handle the success value, the failure, and null. For more information, see [Union declarations](../../language-reference/builtin-types/union.md#union-declarations) and [Union conversions](../../language-reference/builtin-types/union.md#union-conversions). + +## Reuse a generic union across numeric types + +Sensors report at different resolutions: a contact sensor uses a `byte`, a position sensor uses a `short`, and a counter uses an `int`. Rather than write a union per type, write one generic union and instantiate it with each numeric type. + +1. In `SmartHome.Core`, add a file named `Sample.cs` and declare the `Sample` union. It holds either an in-range reading of type `T` or a `Saturated` marker for a sensor that railed. Give the union a body that adds an `InRange` property: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Sample.cs" id="SampleUnion"::: + +1. Add a `Normalize` method that scales any reading to a fraction of full scale: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Sample.cs" id="SampleConsume"::: + +The `where T : struct, INumber` constraint keeps `T` a non-nullable numeric value type and lets a single method process every numeric width through arithmetic. The same `Normalize` method works for a `Sample`, a `Sample`, or a `Sample`. Because `Saturated` is a value type and `T` is constrained to a value type, neither case is nullable, so the switch is exhaustive without a null arm. The `InRange` property shows that a union declaration can carry its own members and pattern over `this`. For more information, see [Union declarations](../../language-reference/builtin-types/union.md#union-declarations). + +## Build a custom union that avoids boxing + +A union declaration is a struct that stores its value in a single `object?` field, so a value-type case boxes when you store it. For performance-sensitive code, implement the union pattern by hand to store the value without boxing. + +1. In `SmartHome.Core`, add a file named `Quantity.cs`. Apply the `[Union]` attribute to a struct, and provide the access members the compiler uses to match each case: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Quantity.cs" id="QuantityUnion"::: + +1. Add a method that consumes the custom union the same way you consume a union declaration: + + :::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.Core/Quantity.cs" id="QuantityConsume"::: + +The `HasValue` property and the `TryGetValue` overloads let the compiler match each case without boxing. The struct stores the value in a `double` field and a discriminator, so neither the `int` case nor the `double` case allocates. The switch over `int` and `double` is exhaustive, and no null arm is needed because neither case type is nullable. For more information, see [Custom union types](../../language-reference/builtin-types/union.md#custom-union-types). + +> [!NOTE] +> Another scenario for a custom union is to add language support to an existing type that models a union. If your app has union-like types you created before C# had `union` types, apply the `Union` attribute and implement the `IUnion` interface on those types. The compiler then gives your custom type the same language support as a union declaration. For details, see the [Unions feature specification](~/_csharplang/proposals/unions.md). + +## Run the sample + +The console app drives each union. Replace the contents of `Program.cs`: + +:::code language="csharp" source="snippets/shared/telemetry-monitor/SmartHome.App/Program.cs" id="UnionMain"::: + +Run the app: + +```dotnetcli +dotnet run --project SmartHome.App +``` + +The readings, results, samples, and quantities each print through their exhaustive switches: + +```output +Reading: 23.5 +Reading: on +Reading: offline +Reading: no reading +Success: 42 +Failure: sensor timed out +Sample: 78% (in range: True) +Sample: 100% (in range: False) +3 items +2.50 units +``` + +## Summary + +You built the readings layer of a smart-home telemetry monitor and, in the process, worked through the core union scenarios. You: + +- Declared a `Reading` union and read it with an exhaustive switch, letting the compiler flag any case you don't handle. +- Handled a nullable case, where the compiler requires a `null` arm. +- Replaced a hand-rolled result type with a generic `Result` union that models success or failure without invalid states. +- Reused a generic `Sample` union across several numeric types with a constraint, and added members to the union declaration. +- Built a custom `[Union]` struct that avoids boxing for performance-sensitive code. + +## Related content + +- [Closed hierarchies tutorial](closed-hierarchies.md) +- [Pattern matching overview](../../fundamentals/functional/pattern-matching.md) +- [What's new in C# 15](../csharp-15.md) From 8acdb82cd5fff1ea8d118e489a7205f0435d66b3 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 7 Jul 2026 15:00:50 -0400 Subject: [PATCH 04/26] sort the C# redirection file (#54666) A few PRs back, it got unsorted when a few PRs with redirections were reviewed and merged. Since then, any additional redirection and sort shows a huge number of changes. This PR puts sorts the redirection so future PRs with redirections are cleaner. --- .openpublishing.redirection.csharp.json | 1210 +++++++++++------------ 1 file changed, 605 insertions(+), 605 deletions(-) diff --git a/.openpublishing.redirection.csharp.json b/.openpublishing.redirection.csharp.json index 29128b703ea02..25c1563e1f38b 100644 --- a/.openpublishing.redirection.csharp.json +++ b/.openpublishing.redirection.csharp.json @@ -1,605 +1,5 @@ { "redirections": [ - { - "source_path_from_root": "/docs/csharp/how-to/compare-strings.md", - "redirect_url": "/dotnet/csharp/fundamentals/strings/common-tasks/compare", - "redirect_document_id": true - }, - { - "source_path_from_root": "/docs/csharp/how-to/concatenate-multiple-strings.md", - "redirect_url": "/dotnet/csharp/fundamentals/strings/common-tasks/concatenate", - "redirect_document_id": true - }, - { - "source_path_from_root": "/docs/csharp/how-to/modify-string-contents.md", - "redirect_url": "/dotnet/csharp/fundamentals/strings/common-tasks/modify", - "redirect_document_id": true - }, - { - "source_path_from_root": "/docs/csharp/tutorials/string-interpolation.md", - "redirect_url": "/dotnet/csharp/fundamentals/tutorials/string-interpolation", - "redirect_document_id": true - }, - { - "source_path_from_root": "/docs/csharp/fundamentals/null-safety/migration-strategies.md", - "redirect_url": "/dotnet/csharp/advanced-topics/update-applications/nullable-migration-strategies" - }, - { - "source_path_from_root": "/docs/csharp/fundamentals/types/anonymous-types.md", - "redirect_url": "/dotnet/csharp/fundamentals/types/tuples" - }, - { - "source_path_from_root": "/docs/csharp/fundamentals/types/namespaces.md", - "redirect_url": "/dotnet/csharp/fundamentals/program-structure/namespaces" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0006.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0007.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0016.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1564.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1616.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1763.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs2032.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0017.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0028.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0031.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0059.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0123.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0144.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/new-object-creation-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0148.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0220.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0221.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0273.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0274.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0275.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0276.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0406.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0409.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0410.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0411.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0442.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0452.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0453.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0456.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0463.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0543.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0544.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0546.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0547.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0548.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0594.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0610.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0644.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0652.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0659.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0693.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0699.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0701.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0704.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0712.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/new-object-creation-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0718.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1021.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0080.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0081.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0305.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0306.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0307.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0308.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0312.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0313.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0314.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0315.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0401.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0402.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0403.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0405.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0407.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0412.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0449.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0450.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0451.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0454.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0455.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0694.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0695.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0698.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0706.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0717.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0104.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0104" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0434.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0434" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0435.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0435" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0436.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0436" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0437.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0437" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs0438.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0438" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1022.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs1022" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1526.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/new-object-creation-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1555.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1556.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1557.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1558.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1559.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1599.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1617.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/feature-version-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1638.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/feature-version-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1664.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1668.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1715.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1719.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1720.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1948.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs1958.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs2008.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs2017.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs2019.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs2029.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs2036.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs3012.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs3013.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs3024.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs5001.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0304.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0310.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0311.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0413.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0417.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0467.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0702.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0703.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" - }, - { - "source_path_from_root": "/docs/csharp/misc/cs8500.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/binary-literals.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/lexical-structure#6453-integer-literals" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/digit-separators.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/lexical-structure#6453-integer-literals" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/local-functions.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/statements#1364-local-function-declarations" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/throw-expression.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1215-the-throw-expression-operator" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/out-var.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1217-declaration-expressions" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/pattern-matching.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/patterns" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.0/task-types.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/classes#15152-task-type-builder-pattern" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.1/async-main.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/basic-concepts#71-application-startup" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.1/target-typed-default.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12719-default-value-expressions" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.1/infer-tuple-names.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/types#8311-tuple-types" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.1/generics-pattern-match.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/patterns" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.2/conditional-ref.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1219-conditional-operator" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.2/non-trailing-named-arguments.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12621-general" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.2/private-protected.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/classes#1536-access-modifiers" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.2/readonly-ref.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/variables#97-reference-variables-and-returns" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.2/readonly-struct.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/structs#1624-struct-interfaces" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.2/span-safety.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/variables#97-reference-variables-and-returns" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/auto-prop-field-attrs.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/attributes#223-attribute-specification" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/blittable.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/classes#1525-type-parameter-constraints" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/expression-variables-in-initializers.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1217-declaration-expressions" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/improved-overload-candidates.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12642-applicable-function-member" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/indexing-movable-fixed-fields.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/unsafe-code#2383-fixed-size-buffers-in-expressions" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/leading-digit-separator.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/lexical-structure#6453-integer-literals" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/pattern-based-fixed.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/unsafe-code#247-the-fixed-statement" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/ref-local-reassignment.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/variables#97-reference-variables-and-returns" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/stackalloc-array-initializers.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12821-stack-allocation" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-7.3/tuple-equality.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#121211-tuple-equality-operators" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-9.0/nullable-reference-types-specification.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/types#893-nullable-reference-types" - }, - { - "source_path_from_root": "/redirections/proposals/csharp-10.0/generic-attributes.md", - "redirect_url": "/dotnet/csharp/language-reference/language-specification/attributes#232-attribute-classes" - }, { "source_path_from_root": "/docs/csharp/async.md", "redirect_url": "/dotnet/csharp/asynchronous-programming" @@ -676,10 +76,22 @@ "source_path_from_root": "/docs/csharp/features.md", "redirect_url": "/dotnet/csharp/programming-guide/concepts" }, + { + "source_path_from_root": "/docs/csharp/fundamentals/null-safety/migration-strategies.md", + "redirect_url": "/dotnet/csharp/advanced-topics/update-applications/nullable-migration-strategies" + }, { "source_path_from_root": "/docs/csharp/fundamentals/null-safety/resolve-warnings.md", "redirect_url": "/dotnet/csharp/fundamentals/null-safety/common-tasks/resolve-warnings" }, + { + "source_path_from_root": "/docs/csharp/fundamentals/types/anonymous-types.md", + "redirect_url": "/dotnet/csharp/fundamentals/types/tuples" + }, + { + "source_path_from_root": "/docs/csharp/fundamentals/types/namespaces.md", + "redirect_url": "/dotnet/csharp/fundamentals/program-structure/namespaces" + }, { "source_path_from_root": "/docs/csharp/generics.md", "redirect_url": "/dotnet/csharp/fundamentals/types/generics" @@ -751,6 +163,21 @@ "source_path_from_root": "/docs/csharp/getting-started/with-visual-studio.md", "redirect_url": "/dotnet/core/tutorials/with-visual-studio" }, + { + "source_path_from_root": "/docs/csharp/how-to/compare-strings.md", + "redirect_url": "/dotnet/csharp/fundamentals/strings/common-tasks/compare", + "redirect_document_id": true + }, + { + "source_path_from_root": "/docs/csharp/how-to/concatenate-multiple-strings.md", + "redirect_url": "/dotnet/csharp/fundamentals/strings/common-tasks/concatenate", + "redirect_document_id": true + }, + { + "source_path_from_root": "/docs/csharp/how-to/modify-string-contents.md", + "redirect_url": "/dotnet/csharp/fundamentals/strings/common-tasks/modify", + "redirect_document_id": true + }, { "source_path_from_root": "/docs/csharp/how-to/parse-strings-using-split.md", "redirect_url": "/dotnet/csharp/fundamentals/strings/split" @@ -803,6 +230,18 @@ "source_path_from_root": "/docs/csharp/language-reference/builtin-types/nint-nuint.md", "redirect_url": "/dotnet/csharp/language-reference/builtin-types/integral-numeric-types#native-sized-integers" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0006.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0007.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0016.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0034.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overload-resolution" @@ -851,6 +290,30 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0270.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0304.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0310.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0311.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0413.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0417.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0467.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0518.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0518" @@ -891,6 +354,14 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0686.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/interface-implementation-errors" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0702.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0703.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs0767.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors" @@ -963,10 +434,18 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1502.md", "redirect_url": "/dotnet/csharp/misc/cs1503" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1564.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1614.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1616.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1656.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" @@ -1015,6 +494,10 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1751.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1763.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1919.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" @@ -1051,6 +534,10 @@ "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1997.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors" }, + { + "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs2032.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs3007.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" @@ -2253,10 +1740,22 @@ "source_path_from_root": "/docs/csharp/misc/cs0012.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/assembly-references" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0017.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0022.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0028.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0031.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0035.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" @@ -2269,6 +1768,22 @@ "source_path_from_root": "/docs/csharp/misc/cs0057.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0059.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0080.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0081.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0104.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0104" + }, { "source_path_from_root": "/docs/csharp/misc/cs0105.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" @@ -2281,6 +1796,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0121.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overload-resolution" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0123.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, { "source_path_from_root": "/docs/csharp/misc/cs0132.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#static-constructors" @@ -2289,6 +1808,14 @@ "source_path_from_root": "/docs/csharp/misc/cs0138.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0144.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/new-object-creation-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0148.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, { "source_path_from_root": "/docs/csharp/misc/cs0171.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/feature-version-errors" @@ -2369,6 +1896,14 @@ "source_path_from_root": "/docs/csharp/misc/cs0218.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0220.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0221.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0225.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays" @@ -2433,6 +1968,22 @@ "source_path_from_root": "/docs/csharp/misc/cs0267.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/partial-declarations" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0273.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0274.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0275.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0276.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0277.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/interface-implementation-errors" @@ -2441,14 +1992,86 @@ "source_path_from_root": "/docs/csharp/misc/cs0282.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/partial-declarations" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0305.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0306.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0307.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0308.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0312.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0313.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0314.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0315.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0400.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/assembly-references" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0401.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0402.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0403.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0404.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0405.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0406.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0407.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/lambda-expression-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0409.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0410.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0411.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0412.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0415.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" @@ -2477,6 +2100,26 @@ "source_path_from_root": "/docs/csharp/misc/cs0432.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0434.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0434" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0435.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0435" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0436.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0436" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0437.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0437" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0438.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs0438" + }, { "source_path_from_root": "/docs/csharp/misc/cs0439.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" @@ -2485,6 +2128,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0440.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0442.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0447.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" @@ -2493,6 +2140,38 @@ "source_path_from_root": "/docs/csharp/misc/cs0448.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0449.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0450.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0451.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0452.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0453.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0454.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0455.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0456.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0457.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overload-resolution" @@ -2505,6 +2184,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0460.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/interface-implementation-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0463.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0466.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays" @@ -2569,6 +2252,26 @@ "source_path_from_root": "/docs/csharp/misc/cs0541.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/interface-implementation-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0543.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0544.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0546.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0547.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0548.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0550.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/interface-implementation-errors" @@ -2653,6 +2356,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0591.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0594.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0599.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch" @@ -2661,6 +2368,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0609.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0610.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0611.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" @@ -2705,6 +2416,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0643.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/parameter-argument-mismatch" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0644.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, { "source_path_from_root": "/docs/csharp/misc/cs0646.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" @@ -2713,6 +2428,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0647.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0652.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0653.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" @@ -2729,6 +2448,10 @@ "source_path_from_root": "/docs/csharp/misc/cs0658.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0659.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0660.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" @@ -2750,21 +2473,65 @@ "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays" }, { - "source_path_from_root": "/docs/csharp/misc/cs0685.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" + "source_path_from_root": "/docs/csharp/misc/cs0685.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0687.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0693.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0694.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0695.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0698.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0699.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0701.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0704.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" }, { - "source_path_from_root": "/docs/csharp/misc/cs0687.md", - "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" + "source_path_from_root": "/docs/csharp/misc/cs0706.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" }, { "source_path_from_root": "/docs/csharp/misc/cs0710.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/constructor-errors#constructor-declarations" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0712.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/new-object-creation-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0715.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0717.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0718.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0719.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" @@ -2921,6 +2688,14 @@ "source_path_from_root": "/docs/csharp/misc/cs1020.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overload-resolution" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1021.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1022.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors#cs1022" + }, { "source_path_from_root": "/docs/csharp/misc/cs1024.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/preprocessor-errors" @@ -3013,6 +2788,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1517.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/preprocessor-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1526.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/new-object-creation-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1529.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" @@ -3041,6 +2820,26 @@ "source_path_from_root": "/docs/csharp/misc/cs1554.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1555.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1556.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1557.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1558.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1559.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1560.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/preprocessor-errors" @@ -3057,6 +2856,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1586.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1599.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, { "source_path_from_root": "/docs/csharp/misc/cs1605.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors" @@ -3069,6 +2872,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1611.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1617.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/feature-version-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1618.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" @@ -3133,6 +2940,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1637.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/iterator-yield" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1638.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/feature-version-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1641.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" @@ -3177,6 +2988,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1663.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1664.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1665.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" @@ -3189,6 +3004,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1667.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/attribute-usage-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1668.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/misc/cs1670.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/params-arrays" @@ -3265,6 +3084,18 @@ "source_path_from_root": "/docs/csharp/misc/cs1714.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/assembly-references" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1715.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1719.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs1720.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1730.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" @@ -3309,6 +3140,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1945.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/expression-tree-restrictions" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1948.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1950.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" @@ -3329,22 +3164,66 @@ "source_path_from_root": "/docs/csharp/misc/cs1954.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1958.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs2008.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs2017.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs2019.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs2029.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/misc/cs2034.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/using-directive-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs2036.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/misc/cs3006.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overload-resolution" }, + { + "source_path_from_root": "/docs/csharp/misc/cs3012.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs3013.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/invalid-build-command-line" + }, { "source_path_from_root": "/docs/csharp/misc/cs3016.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs3024.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/generic-type-parameters-errors" + }, { "source_path_from_root": "/docs/csharp/misc/CS4009.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs5001.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/entry-point-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs8500.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs8506.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/pattern-matching-warnings" @@ -5603,6 +5482,11 @@ "source_path_from_root": "/docs/csharp/tutorials/records.md", "redirect_url": "/dotnet/csharp/fundamentals/tutorials/records" }, + { + "source_path_from_root": "/docs/csharp/tutorials/string-interpolation.md", + "redirect_url": "/dotnet/csharp/fundamentals/tutorials/string-interpolation", + "redirect_document_id": true + }, { "source_path_from_root": "/docs/csharp/tutorials/upgrade-to-nullable-references.md", "redirect_url": "/dotnet/csharp/advanced-topics/update-applications/nullable-migration-strategies" @@ -5712,6 +5596,122 @@ { "source_path_from_root": "/docs/csharp/write-safe-efficient-code.md", "redirect_url": "/dotnet/csharp/advanced-topics/performance" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-10.0/generic-attributes.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/attributes#232-attribute-classes" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/binary-literals.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/lexical-structure#6453-integer-literals" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/digit-separators.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/lexical-structure#6453-integer-literals" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/local-functions.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/statements#1364-local-function-declarations" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/out-var.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1217-declaration-expressions" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/pattern-matching.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/patterns" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/task-types.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/classes#15152-task-type-builder-pattern" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.0/throw-expression.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1215-the-throw-expression-operator" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.1/async-main.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/basic-concepts#71-application-startup" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.1/generics-pattern-match.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/patterns" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.1/infer-tuple-names.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/types#8311-tuple-types" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.1/target-typed-default.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12719-default-value-expressions" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.2/conditional-ref.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1219-conditional-operator" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.2/non-trailing-named-arguments.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12621-general" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.2/private-protected.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/classes#1536-access-modifiers" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.2/readonly-ref.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/variables#97-reference-variables-and-returns" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.2/readonly-struct.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/structs#1624-struct-interfaces" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.2/span-safety.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/variables#97-reference-variables-and-returns" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/auto-prop-field-attrs.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/attributes#223-attribute-specification" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/blittable.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/classes#1525-type-parameter-constraints" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/expression-variables-in-initializers.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#1217-declaration-expressions" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/improved-overload-candidates.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12642-applicable-function-member" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/indexing-movable-fixed-fields.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/unsafe-code#2383-fixed-size-buffers-in-expressions" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/leading-digit-separator.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/lexical-structure#6453-integer-literals" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/pattern-based-fixed.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/unsafe-code#247-the-fixed-statement" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/ref-local-reassignment.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/variables#97-reference-variables-and-returns" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/stackalloc-array-initializers.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#12821-stack-allocation" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-7.3/tuple-equality.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/expressions#121211-tuple-equality-operators" + }, + { + "source_path_from_root": "/redirections/proposals/csharp-9.0/nullable-reference-types-specification.md", + "redirect_url": "/dotnet/csharp/language-reference/language-specification/types#893-nullable-reference-types" } ] -} \ No newline at end of file +} From 3cfca6f3c1e75151c97c55b28f220f1c7db6c829 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Tue, 7 Jul 2026 12:11:11 -0700 Subject: [PATCH 05/26] Delete .github/workflows/profanity-filter.yml (#54667) --- .github/workflows/profanity-filter.yml | 32 -------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .github/workflows/profanity-filter.yml diff --git a/.github/workflows/profanity-filter.yml b/.github/workflows/profanity-filter.yml deleted file mode 100644 index 98c942595f4b5..0000000000000 --- a/.github/workflows/profanity-filter.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Profanity filter - -on: - issue_comment: - types: [created, edited] - issues: - types: [opened, edited, reopened] - pull_request: - types: [opened, edited, reopened] - -permissions: - issues: write - pull-requests: write - -jobs: - apply-filter: - name: Apply profanity filter - runs-on: ubuntu-latest - - steps: - - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 - with: - egress-policy: audit - - - name: Profanity filter - if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'github-actions[bot]' }} - uses: IEvangelist/profanity-filter@4655e7a15cd4a13a5c9b13affed04a487f556083 # main - id: profanity-filter - with: - token: ${{ secrets.GITHUB_TOKEN }} - replacement-strategy: redacted-rectangle From fd1fbf2c54d6552d36248b8b4663bdb08b67e3c0 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Jul 2026 12:30:19 -0700 Subject: [PATCH 06/26] Document InlineArrayAttribute is the correct approach for fixed-size buffers (#50898) * Initial plan * Add InlineArrayAttribute reference to StructLayoutAttribute docs Co-authored-by: agocke <515774+agocke@users.noreply.github.com> * Change examples from class to struct for consistency Co-authored-by: agocke <515774+agocke@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Aaron R Robinson * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @AaronRobinsonMSFT * Clarify comment about buffer allocation in UseBuffer Updated comment to clarify memory allocation issue. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: agocke <515774+agocke@users.noreply.github.com> Co-authored-by: Aaron R Robinson Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../apply-interop-attributes.md | 2 +- .../customize-struct-marshalling.md | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/standard/native-interop/apply-interop-attributes.md b/docs/standard/native-interop/apply-interop-attributes.md index 6c8b3f663e324..6ec63fa324b2e 100644 --- a/docs/standard/native-interop/apply-interop-attributes.md +++ b/docs/standard/native-interop/apply-interop-attributes.md @@ -48,7 +48,7 @@ The namespace provides three categories of ||Indicates that the data in a field or parameter must be marshalled from a called object back to its caller.| ||Suppresses the HRESULT or retval signature transformation that normally takes place during interoperation calls. The attribute affects marshalling as well as type library exporting.

COM interop tools can apply this attribute.| ||Specifies the ProgID of a .NET class. Can be used to attribute classes.| -||Controls the physical layout of the fields of a class.

COM interop tools can apply this attribute.| +||Controls the physical layout of the fields of a class. For managed fixed-size buffers, see [Fixed-size buffers and inline arrays](customize-struct-marshalling.md#fixed-size-buffers-and-inline-arrays) and .

COM interop tools can apply this attribute.| ## Conversion-Tool Attributes diff --git a/docs/standard/native-interop/customize-struct-marshalling.md b/docs/standard/native-interop/customize-struct-marshalling.md index 4438549c39536..d2f1eb2948498 100644 --- a/docs/standard/native-interop/customize-struct-marshalling.md +++ b/docs/standard/native-interop/customize-struct-marshalling.md @@ -26,6 +26,61 @@ Sometimes the default marshalling rules for structures aren't exactly what you n ❌ AVOID using `LayoutKind.Explicit` when marshalling structures on non-Windows platforms if you need to target runtimes before .NET Core 3.0. The .NET Core runtime before 3.0 doesn't support passing explicit structures by value to native functions on Intel or AMD 64-bit non-Windows systems. However, the runtime supports passing explicit structures by reference on all platforms. +## Fixed-size buffers and inline arrays + +If you need to define a fixed-size buffer in a structure, don't use the property to allocate extra space. The `Size` property controls the unmanaged layout of the type (the layout used when calling `Marshal.StructureToPtr`) and only affects the managed layout for blittable types. For non-blittable types, the runtime only allocates space based on the actual fields, which can lead to memory corruption if you attempt to use the extra space. + +❌ AVOID using `StructLayoutAttribute.Size` to create fixed-size buffers in managed types. + +✔️ DO use to define fixed-size buffers in modern .NET (C# 12 and later). + +The following example shows the incorrect approach that can lead to memory corruption: + +```csharp +// ❌ DON'T: This is dangerous and can corrupt memory +[StructLayout(LayoutKind.Explicit, Size = 100)] +struct UnsafeBuffer +{ + [FieldOffset(0)] + private byte b; + + unsafe void UseBuffer() + { + fixed (byte* p = &b) + { + // This may interpret p as a 100-byte buffer, but only 1 byte is allocated + // Writing beyond the first byte corrupts memory + } + } +} +``` + +Instead, use `InlineArrayAttribute` to create a properly sized buffer: + +```csharp +// ✔️ DO: Use InlineArrayAttribute for fixed-size buffers +struct SafeBuffer +{ + private Buffer100 buffer; + + unsafe void UseBuffer() + { + fixed (byte* p = &buffer[0]) + { + // The buffer is guaranteed to be 100 bytes + } + } +} + +[InlineArray(100)] +internal struct Buffer100 +{ + private byte _element0; +} +``` + +For more information about inline arrays, see the [C# language reference](../../csharp/language-reference/builtin-types/struct.md#inline-arrays). + ## Customizing Boolean field marshalling Native code has many different Boolean representations. On Windows alone, there are three ways to represent Boolean values. The runtime doesn't know the native definition of your structure, so the best it can do is make a guess on how to marshal your Boolean values. The .NET runtime provides a way to indicate how to marshal your Boolean field. The following examples show how to marshal .NET `bool` to different native Boolean types. From 34593ddd0173186c7930898a919593a8e6fa65b5 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Tue, 7 Jul 2026 15:09:31 -0700 Subject: [PATCH 07/26] Reword some regex safety warnings (#54621) --- docs/standard/base-types/best-practices-regex.md | 16 ++++++++++++---- .../base-types/regular-expression-options.md | 5 ++++- includes/regex.md | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/standard/base-types/best-practices-regex.md b/docs/standard/base-types/best-practices-regex.md index a3e3ebb38fd62..3a89130f85cf4 100644 --- a/docs/standard/base-types/best-practices-regex.md +++ b/docs/standard/base-types/best-practices-regex.md @@ -16,15 +16,20 @@ ms.assetid: 618e5afb-3a97-440d-831a-70e4c526a51c The regular expression engine in .NET is a powerful, full-featured tool that processes text based on pattern matches rather than on comparing and matching literal text. In most cases, it performs pattern matching rapidly and efficiently. However, in some cases, the regular expression engine can appear to be slow. In extreme cases, it can even appear to stop responding as it processes a relatively small input over the course of hours or even days. -This article outlines some of the best practices that developers can adopt to ensure that their regular expressions achieve optimal performance. +This article outlines some of the best practices that developers can adopt to ensure that their regular expressions achieve optimal performance and robustness. -[!INCLUDE [regex](../../../includes/regex.md)] +> [!WARNING] +> Unrestricted use of regular expressions with untrusted input can subject applications to [denial-of-service attacks](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS). The .NET regular expression engine offers options to mitigate these attacks. For more information, see [Consider the input source](#consider-the-input-source), [Take charge of backtracking](#take-charge-of-backtracking), and [Use time-out values](#use-time-out-values). +> +> The .NET regular expression engine does not offer protection against untrusted *patterns*, and applications should not create regular expression patterns from untrusted user-provided values. For more information, see [Use trusted patterns](#use-trusted-patterns). ## Use trusted patterns -The .NET regular expression engine is designed with the assumption that patterns are trusted, that is, they are authored or reviewed by the application developer, not supplied by end users or other untrusted sources. Patterns can cause excessive resource consumption regardless of the input text, and the regular expression engine does not attempt to guard against hostile patterns. +The .NET regular expression engine distinguishes *patterns* (the regular expression itself, such as `^[0-9A-Za-z]+$`) from the *input text* (the string being evaluated against the regular expression, such as `123AbC456`). These values are typically passed to the `Regex` APIs through arguments named *pattern* and *input*, respectively. + +These APIs are designed with the assumption that patterns are trusted, that is, they are authored or reviewed by the application developer, not supplied by end users or other untrusted sources. Patterns can cause excessive resource consumption regardless of the input text, and the regular expression engine does not attempt to guard against hostile patterns. -If your application needs to accept search expressions from users, avoid passing user input directly as a regex pattern. Instead, consider these alternatives: +If your application needs to accept search expressions from users, avoid passing user-provided values directly as a regex pattern. Instead, consider these alternatives: - Support a restricted search syntax (such as simple wildcards or substring matching) that you translate into a regex pattern internally. - Use to treat any user-supplied text as a literal string within a pattern. @@ -222,6 +227,9 @@ The regular expression time-out interval defines the period of time that the reg If you've defined a time-out interval and a match isn't found at the end of that interval, the regular expression method throws a exception. In your exception handler, you can choose to retry the match with a longer time-out interval, abandon the match attempt and assume that there's no match, or abandon the match attempt and log the exception information for future analysis. +> [!WARNING] +> Time-out values are not intended as a security boundary against malicious *patterns*. For more information, see [Use trusted patterns](#use-trusted-patterns). + The following example defines a `GetWordData` method that instantiates a regular expression with a time-out interval of 350 milliseconds to calculate the number of words and average number of characters in a word in a text document. If the matching operation times out, the time-out interval is increased by 350 milliseconds and the object is reinstantiated. If the new time-out interval exceeds one second, the method rethrows the exception to the caller. [!code-csharp[Conceptual.RegularExpressions.BestPractices#12](./snippets/regex/csharp/timeout1.cs#12)] diff --git a/docs/standard/base-types/regular-expression-options.md b/docs/standard/base-types/regular-expression-options.md index 5d16d1e83da21..f7dfe3a455b9a 100644 --- a/docs/standard/base-types/regular-expression-options.md +++ b/docs/standard/base-types/regular-expression-options.md @@ -398,7 +398,10 @@ The following example is identical to the previous example, except that the stat ## NonBacktracking mode -By default, .NET's regex engine uses *backtracking* to try to find pattern matches. A backtracking engine is one that tries to match one pattern, and if that fails, goes backs and tries to match an alternate pattern, and so on. A backtracking engine is very fast for typical cases, but slows down as the number of pattern alternations increases, which can lead to *catastrophic backtracking*. The option, which was introduced in .NET 7, doesn't use backtracking and avoids that worst-case scenario. Its goal is to provide consistently good behavior, regardless of the input being searched. +By default, .NET's regex engine uses *backtracking* to try to find pattern matches. A backtracking engine is one that tries to match one pattern, and if that fails, goes back and tries to match an alternate pattern, and so on. A backtracking engine is very fast for typical cases, but slows down as the number of pattern alternations increases, which can lead to *catastrophic backtracking*. The option, which was introduced in .NET 7, doesn't use backtracking and avoids that worst-case scenario. Its goal is to provide consistently good behavior, regardless of the input being searched. + +> [!WARNING] +> The .NET regex engine assumes the *pattern* is trusted. NonBacktracking mode doesn't change this assumption: it guards against expensive *input*, not against actively malicious *patterns*. For more information, see [Use trusted patterns](best-practices-regex.md#use-trusted-patterns). The option doesn't support everything the other built-in engines support. In particular, the option can't be used in conjunction with , , or . It also doesn't allow for the following constructs in the pattern: diff --git a/includes/regex.md b/includes/regex.md index dac95ae302513..fcee819c5e887 100644 --- a/includes/regex.md +++ b/includes/regex.md @@ -1,3 +1,3 @@ > [!WARNING] -> When using to process untrusted input, pass a timeout. A malicious user can provide input to `RegularExpressions`, causing a [Denial-of-Service attack](https://www.cisa.gov/news-events/news/understanding-denial-service-attacks). ASP.NET Core framework APIs that use `RegularExpressions` pass a timeout. +> Unrestricted use of with untrusted input can subject applications to [denial-of-service attacks](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS). Consult [Best practices for regular expressions in .NET](../docs/standard/base-types/best-practices-regex.md) for guidance on how to safely use .NET regular expressions with untrusted input. From 6852605342817c6d3c20387a466e5e098cb5347f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:31:10 -0700 Subject: [PATCH 08/26] Breaking change: Document dnx scripts bypassing global.json SDK selection (#54645) --- docs/core/compatibility/10.md | 1 + docs/core/compatibility/11.md | 1 + .../sdk/11/dnx-scripts-bypass-global-json.md | 40 +++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + docs/core/tools/dotnet-tool-exec.md | 2 +- 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 docs/core/compatibility/sdk/11/dnx-scripts-bypass-global-json.md diff --git a/docs/core/compatibility/10.md b/docs/core/compatibility/10.md index e3705fdec883e..134934b9f8eb3 100644 --- a/docs/core/compatibility/10.md +++ b/docs/core/compatibility/10.md @@ -121,6 +121,7 @@ See [Breaking changes in EF Core 10](/ef/core/what-is-new/ef-core-10.0/breaking- | [Default workload configuration from 'loose manifests' to 'workload sets' mode](sdk/10.0/default-workload-config.md) | Behavioral change | | [`DefineConstants` for target frameworks not available at evaluation time](sdk/10.0/defineconstants-not-available-at-evaluation.md) | Behavioral change | | [Code coverage EnableDynamicNativeInstrumentation defaults to false](sdk/10.0/code-coverage-dynamic-native-instrumentation.md) | Behavioral change | +| [dnx scripts bypass global.json SDK selection](sdk/11/dnx-scripts-bypass-global-json.md) | Behavioral change | | [dnx.ps1 file is no longer included in .NET SDK](sdk/10.0/dnx-ps1-removed.md) | Source incompatible | | [Double quotes in file-level directives are disallowed](sdk/10.0/file-level-directive-double-quotes.md) | Source incompatible | | [`dotnet new sln` defaults to SLNX file format](sdk/10.0/dotnet-new-sln-slnx-default.md) | Behavioral change | diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index 5a974af91ea77..7450fa0d83314 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -95,6 +95,7 @@ See [Breaking changes in EF Core 11](/ef/core/what-is-new/ef-core-11.0/breaking- | Title | Type of change | |-------------------------------------------------------------------|-------------------| +| [dnx scripts bypass global.json SDK selection](sdk/11/dnx-scripts-bypass-global-json.md) | Behavioral change | | [mono launch target not set for .NET Framework apps](sdk/11/mono-launch-target-removed.md) | Behavioral change | | [NU1703 warns for packages that use deprecated MonoAndroid framework assets](sdk/11/nu1703-deprecated-monoandroid-framework.md) | Source incompatible | | [Template engine packages no longer support netstandard2.0](sdk/11/template-engine-netstandard.md) | Binary/source incompatible | diff --git a/docs/core/compatibility/sdk/11/dnx-scripts-bypass-global-json.md b/docs/core/compatibility/sdk/11/dnx-scripts-bypass-global-json.md new file mode 100644 index 0000000000000..6e260c4175300 --- /dev/null +++ b/docs/core/compatibility/sdk/11/dnx-scripts-bypass-global-json.md @@ -0,0 +1,40 @@ +--- +title: "Breaking change: dnx scripts bypass global.json SDK selection" +description: "Learn about the breaking change in .NET 11 where the dnx and dnx.cmd scripts no longer respect global.json for SDK selection." +ms.date: 07/05/2026 +ai-usage: ai-assisted +--- + +# dnx scripts bypass global.json SDK selection + +The `dnx` and `dnx.cmd` scripts no longer use the .NET muxer to select the SDK version. Instead, they find the newest installed SDK and invoke it directly, which bypasses any `global.json` file in the working directory. + +## Version introduced + +.NET 10 SDK 10.0.302, 10.0.400, and .NET 11 Preview 6 + +## Previous behavior + +Previously, the `dnx` scripts invoked `dotnet dnx`, which relied on the .NET muxer to select the SDK version based on any `global.json` file in the working directory. If `global.json` pinned an SDK version that predated .NET 10, the scripts failed with the following error: + +```output +Unrecognized command or argument 'execute' +``` + +Starting with .NET 10 SDK 10.0.302 (and later) and .NET 11 Preview 6, the `dnx` and `dnx.cmd` scripts use `dotnet --list-sdks` to identify the newest installed SDK. They then invoke `dotnet exec /dotnet.dll dnx` directly, bypassing the .NET muxer and any `global.json` SDK pinning. + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +Some .NET CLI commands, including `dnx`, are considered version-independent features that should always run with the newest installed SDK. Relying on `global.json` meant that users who pinned an older SDK version to reduce risk from build-impacting changes also inadvertently broke `dnx`. In folders where a pre-.NET 10 SDK was pinned, the `dnx` command was unavailable, which caused confusing errors and, in some cases, timeouts in tools like Copilot CLI. + +## Recommended action + +To restore the previous behavior where the .NET muxer and `global.json` control SDK selection, run `dotnet dnx` explicitly instead of the `dnx` script. + +## Affected APIs + +None. diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 9d1da27463472..6117c83450f24 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -72,6 +72,8 @@ items: href: maui/11/android-minimum-api-level.md - name: SDK and MSBuild items: + - name: dnx scripts bypass global.json SDK selection + href: sdk/11/dnx-scripts-bypass-global-json.md - name: mono launch target not set for .NET Framework apps href: sdk/11/mono-launch-target-removed.md - name: NU1703 warns for packages that use deprecated MonoAndroid framework assets diff --git a/docs/core/tools/dotnet-tool-exec.md b/docs/core/tools/dotnet-tool-exec.md index 173958aa876d6..2af3fdfe72552 100644 --- a/docs/core/tools/dotnet-tool-exec.md +++ b/docs/core/tools/dotnet-tool-exec.md @@ -41,7 +41,7 @@ When you run `dotnet tool exec`, the command: This command also exists in two other forms for easier use * `dotnet dnx` - A hidden alias for `dotnet tool exec` that is used as a way to easily implement the `dnx` script itself -* `dnx` - A shell script that invokes `dotnet dnx` from the SDK. This script is provided by the installer and is available on `PATH`. It allows for very simple use of tools directly via `dnx `. +* `dnx` - A shell script provided by the installer and available on `PATH`. It allows for simple use of tools directly via `dnx `. ## Arguments From 927385c7f78de4677c5c6d587ed2ae6bb98c83d3 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 7 Jul 2026 20:12:30 -0700 Subject: [PATCH 09/26] Refactor buffer examples to improve safety (#54669) Updated examples to use classes instead of structs for buffer management and added InlineArrayAttribute for safe buffer usage. --- .../customize-struct-marshalling.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/standard/native-interop/customize-struct-marshalling.md b/docs/standard/native-interop/customize-struct-marshalling.md index d2f1eb2948498..cbffa8b64af8b 100644 --- a/docs/standard/native-interop/customize-struct-marshalling.md +++ b/docs/standard/native-interop/customize-struct-marshalling.md @@ -39,7 +39,7 @@ The following example shows the incorrect approach that can lead to memory corru ```csharp // ❌ DON'T: This is dangerous and can corrupt memory [StructLayout(LayoutKind.Explicit, Size = 100)] -struct UnsafeBuffer +class Bad100ByteBuffer { [FieldOffset(0)] private byte b; @@ -48,7 +48,6 @@ struct UnsafeBuffer { fixed (byte* p = &b) { - // This may interpret p as a 100-byte buffer, but only 1 byte is allocated // Writing beyond the first byte corrupts memory } } @@ -59,8 +58,14 @@ Instead, use `InlineArrayAttribute` to create a properly sized buffer: ```csharp // ✔️ DO: Use InlineArrayAttribute for fixed-size buffers -struct SafeBuffer +class Good100ByteBuffer { + [InlineArray(100)] + private struct Buffer100 + { + private byte _element0; + } + private Buffer100 buffer; unsafe void UseBuffer() @@ -71,12 +76,6 @@ struct SafeBuffer } } } - -[InlineArray(100)] -internal struct Buffer100 -{ - private byte _element0; -} ``` For more information about inline arrays, see the [C# language reference](../../csharp/language-reference/builtin-types/struct.md#inline-arrays). From 64695fa225fb11905b71d33e5c4e267fa20c197b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:08:37 -0400 Subject: [PATCH 10/26] Bump the dotnet group with 1 update (#54680) Bumps Refit.HttpClientFactory from 12.0.0 to 13.0.0 --- updated-dependencies: - dependency-name: Refit.HttpClientFactory dependency-version: 13.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/core/extensions/snippets/http/generated/generated.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/extensions/snippets/http/generated/generated.csproj b/docs/core/extensions/snippets/http/generated/generated.csproj index 56119750c4149..757bcbb57b017 100644 --- a/docs/core/extensions/snippets/http/generated/generated.csproj +++ b/docs/core/extensions/snippets/http/generated/generated.csproj @@ -11,7 +11,7 @@ - + From e9750f342c6788ecbc58e5acb76b26129f0fa38e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:09:03 -0400 Subject: [PATCH 11/26] Bump the dotnet group with 2 updates (#54687) Bumps Microsoft.Extensions.AI from 10.6.0 to 10.7.0 Bumps Microsoft.Extensions.AI.OpenAI from 10.6.0 to 10.7.0 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI dependency-version: 10.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.AI.OpenAI dependency-version: 10.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/content-filtering/AIContentFiltering.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ai/how-to/snippets/content-filtering/AIContentFiltering.csproj b/docs/ai/how-to/snippets/content-filtering/AIContentFiltering.csproj index 5bf960341478f..70173243d85c1 100644 --- a/docs/ai/how-to/snippets/content-filtering/AIContentFiltering.csproj +++ b/docs/ai/how-to/snippets/content-filtering/AIContentFiltering.csproj @@ -10,8 +10,8 @@ - - + + From 3cd139f5983c110bcaea253576d1d2f29b289e74 Mon Sep 17 00:00:00 2001 From: pshrote-afk Date: Wed, 8 Jul 2026 19:39:53 +0530 Subject: [PATCH 12/26] Fix typo in README (#54673) --- .../common-web-application-architectures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/modern-web-apps-azure/common-web-application-architectures.md b/docs/architecture/modern-web-apps-azure/common-web-application-architectures.md index e9e280c4f2ac5..428e4f679312c 100644 --- a/docs/architecture/modern-web-apps-azure/common-web-application-architectures.md +++ b/docs/architecture/modern-web-apps-azure/common-web-application-architectures.md @@ -75,7 +75,7 @@ Although this application uses several projects for organizational purposes, it' **Figure 5-4.** Simple deployment of Azure Web App -As application needs grow, more complex and robust deployment solutions may be required. Figure 5-5 shows an example of a more complex deployment plan that supports additional capabilities. +As the application grows, more complex and robust deployment solutions may be required. Figure 5-5 shows an example of a more complex deployment plan that supports additional capabilities. ![Deploying a web app to an Azure App Service](./media/image5-5.png) From ed2862829327eca713a2099506be886901896d49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:15:08 -0400 Subject: [PATCH 13/26] Bump the dotnet group with 1 update (#54689) Bumps Azure.Storage.Blobs from 12.29.0 to 12.29.1 --- updated-dependencies: - dependency-name: Azure.Storage.Blobs dependency-version: 12.29.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../aspnetcore-guidance/MinApiSample/MinApiSample.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/azure/sdk/snippets/aspnetcore-guidance/MinApiSample/MinApiSample.csproj b/docs/azure/sdk/snippets/aspnetcore-guidance/MinApiSample/MinApiSample.csproj index 330da28dbff69..55eb8cde9b0ff 100644 --- a/docs/azure/sdk/snippets/aspnetcore-guidance/MinApiSample/MinApiSample.csproj +++ b/docs/azure/sdk/snippets/aspnetcore-guidance/MinApiSample/MinApiSample.csproj @@ -10,7 +10,7 @@ - + From f84029dbe2495ef16df1d441c8cceea1e9c8a3dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:15:43 -0400 Subject: [PATCH 14/26] Bump the dotnet group with 2 updates (#54692) Bumps Azure.Core from 1.59.0 to 1.60.0 Bumps Microsoft.NET.Test.Sdk from 18.6.0 to 18.7.0 --- updated-dependencies: - dependency-name: Azure.Core dependency-version: 1.60.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../sdk/snippets/unit-testing/UnitTestingSampleApp.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/azure/sdk/snippets/unit-testing/UnitTestingSampleApp.csproj b/docs/azure/sdk/snippets/unit-testing/UnitTestingSampleApp.csproj index d3cafbb5c5401..ae2dd019f5061 100644 --- a/docs/azure/sdk/snippets/unit-testing/UnitTestingSampleApp.csproj +++ b/docs/azure/sdk/snippets/unit-testing/UnitTestingSampleApp.csproj @@ -10,9 +10,9 @@ - + - + From b48b07ff2a0ff4ff1c9556723f563e2b57f4c211 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:16:08 -0400 Subject: [PATCH 15/26] Bump the dotnet group with 1 update (#54693) Bumps Spectre.Console from 0.57.0 to 0.57.1 --- updated-dependencies: - dependency-name: Spectre.Console dependency-version: 0.57.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../resource-monitoring-with-manual-metrics.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/diagnostics/snippets/resource-monitoring-with-manual-metrics/resource-monitoring-with-manual-metrics.csproj b/docs/core/diagnostics/snippets/resource-monitoring-with-manual-metrics/resource-monitoring-with-manual-metrics.csproj index f43a09e41ea84..d8803776079f8 100644 --- a/docs/core/diagnostics/snippets/resource-monitoring-with-manual-metrics/resource-monitoring-with-manual-metrics.csproj +++ b/docs/core/diagnostics/snippets/resource-monitoring-with-manual-metrics/resource-monitoring-with-manual-metrics.csproj @@ -14,7 +14,7 @@ - + From 62dc042327ec11fb3b1cc272c015cffbddfb0a14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:16:26 -0400 Subject: [PATCH 16/26] Bump the dotnet group with 1 update (#54702) Bumps Microsoft.NET.Test.Sdk from 18.6.0 to 18.7.0 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/evaluate-with-reporting/TestAIWithReporting.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/evaluation/snippets/evaluate-with-reporting/TestAIWithReporting.csproj b/docs/ai/evaluation/snippets/evaluate-with-reporting/TestAIWithReporting.csproj index 289919ae1d6a3..e6aa6e6f3f975 100644 --- a/docs/ai/evaluation/snippets/evaluate-with-reporting/TestAIWithReporting.csproj +++ b/docs/ai/evaluation/snippets/evaluate-with-reporting/TestAIWithReporting.csproj @@ -18,7 +18,7 @@ - + From 255accefc273547bd981afe729c304938085683d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:16:50 -0400 Subject: [PATCH 17/26] Bump the dotnet group with 3 updates (#54704) Bumps Microsoft.Extensions.AI.OpenAI from 10.6.0 to 10.7.0 Bumps Microsoft.Extensions.Configuration from 10.0.8 to 10.0.9 Bumps Microsoft.Extensions.Configuration.UserSecrets from 10.0.8 to 10.0.9 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI.OpenAI dependency-version: 10.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.Configuration dependency-version: 10.0.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Configuration.UserSecrets dependency-version: 10.0.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/build-chat-app/azure-openai/ChatAppAI.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ai/quickstarts/snippets/build-chat-app/azure-openai/ChatAppAI.csproj b/docs/ai/quickstarts/snippets/build-chat-app/azure-openai/ChatAppAI.csproj index dc2f053f66ea2..a9d8b36169e01 100644 --- a/docs/ai/quickstarts/snippets/build-chat-app/azure-openai/ChatAppAI.csproj +++ b/docs/ai/quickstarts/snippets/build-chat-app/azure-openai/ChatAppAI.csproj @@ -11,9 +11,9 @@ - - - + + + From 494a9c6a61f7f3e19b56a45f09cdd65ea72d3209 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:17:12 -0400 Subject: [PATCH 18/26] Bump the dotnet group with 1 update (#54705) Bumps Microsoft.Agents.AI.OpenAI from 1.11.0 to 1.12.0 --- updated-dependencies: - dependency-name: Microsoft.Agents.AI.OpenAI dependency-version: 1.12.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj b/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj index 596ae20c6a945..a2a04fd9152f0 100644 --- a/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj +++ b/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj @@ -10,7 +10,7 @@ - +