From 7c06e156065c82795abb7351c8c20dd98e117494 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:44:35 +0000 Subject: [PATCH 01/30] Initial plan From 6b543586e03f5a4d5049a27a712b159691df1f59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:56:44 +0000 Subject: [PATCH 02/30] Apply freshness edits to logging.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/extensions/logging.md | 85 ++++++++++++++++----------------- 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index 341231b29e79d..7254388cd73e2 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -3,7 +3,8 @@ title: Logging in C# author: IEvangelist description: Learn about app logging provided by the Microsoft.Extensions.Logging NuGet package in C#. ms.author: dapine -ms.date: 07/17/2024 +ms.date: 10/21/2025 +ai-usage: ai-assisted --- # Logging in C# and .NET @@ -12,7 +13,7 @@ ms.date: 07/17/2024 ## Get started -This first example shows the basics, but it's only suitable for a trivial console app. This sample console app relies on the following NuGet packages: +This first example shows the basics, but it's only suitable for a trivial console app. This sample console app relies on these NuGet packages: - [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) - [Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) @@ -24,9 +25,8 @@ In the next section you see how to improve the code considering scale, performan The preceding example: - Creates an . The `ILoggerFactory` stores all the configuration that determines where log messages are sent. In this case, you configure the console [logging provider](logging-providers.md) so that log messages are written to the console. -- Creates an with a category named "Program". The [category](#log-category) is a `string` that is associated with each message logged -by the `ILogger` object. It's used to group log messages from the same class (or category) together when searching or filtering logs. -- Calls to log a message at the `Information` level. The [log level](#log-level) indicates the severity of the logged event and is used to filter out less important log messages. The log entry also includes a [message template](#log-message-template) `"Hello World! Logging is {Description}."` and a key-value pair `Description = fun`. The key name (or placeholder) comes from the word inside the curly braces in the template and the value comes from the remaining method argument. +- Creates an with a category named "Program". The [category](#log-category) is a `string` that's associated with each message logged by the `ILogger` object. It groups log messages from the same class (or category) together when searching or filtering logs. +- Calls to log a message at the `Information` level. The [log level](#log-level) indicates the severity of the logged event and filters out less important log messages. The log entry also includes a [message template](#log-message-template) `"Hello World! Logging is {Description}."` and a key-value pair `Description = fun`. The key name (or placeholder) comes from the word inside the curly braces in the template, and the value comes from the remaining method argument. This project file for this example includes two NuGet packages: @@ -36,9 +36,9 @@ This project file for this example includes two NuGet packages: ## Logging in a non-trivial app -There are several changes you should consider making to the previous example when logging in a less trivial scenario: +Consider making these changes to the previous example when logging in a less trivial scenario: -- If your application is using [Dependency Injection (DI)](dependency-injection.md) or a host such as ASP.NET's [WebApplication](/aspnet/core/fundamentals/minimal-apis/webapplication) or [Generic Host](generic-host.md) then you should use `ILoggerFactory` and `ILogger` objects from their respective DI containers rather than creating them directly. For more information, see [Integration with DI and Hosts](#integration-with-hosts-and-dependency-injection). +- If your application uses [Dependency Injection (DI)](dependency-injection.md) or a host such as ASP.NET's [WebApplication](/aspnet/core/fundamentals/minimal-apis/webapplication) or [Generic Host](generic-host.md), use `ILoggerFactory` and `ILogger` objects from their respective DI containers rather than creating them directly. For more information, see [Integration with DI and Hosts](#integration-with-hosts-and-dependency-injection). - Logging [compile-time source generation](logger-message-generator.md) is usually a better alternative to `ILogger` extension methods like `LogInformation`. Logging source generation offers better performance, stronger typing, and avoids spreading `string` constants throughout your methods. The tradeoff is that using this technique requires a bit more code. @@ -48,13 +48,13 @@ There are several changes you should consider making to the previous example whe :::code language="csharp" source="snippets/logging/getting-started-type-category-name/Program.cs" highlight="8"::: -- If you don't use console logs as your sole production monitoring solution, add the [logging providers](logging-providers.md) you plan to use. For example, you could use [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-dotnet#getting-started) to send logs over [OTLP (OpenTelemetry protocol)](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md#enable-log-exporter): +- If you don't use console logs as your sole production monitoring solution, add the [logging providers](logging-providers.md) you plan to use. For example, use [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-dotnet#getting-started) to send logs over [OTLP (OpenTelemetry protocol)](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md#enable-log-exporter): :::code language="csharp" source="snippets/logging/getting-started-open-telemetry/Program.cs" highlight="6-9"::: ## Integration with hosts and dependency injection -If your application is using [Dependency Injection (DI)](dependency-injection.md) or a host such as ASP.NET's [WebApplication](/aspnet/core/fundamentals/minimal-apis/webapplication) or [Generic Host](generic-host.md) then you should use `ILoggerFactory` and `ILogger` objects from the DI container rather than creating them directly. +If your application uses [Dependency Injection (DI)](dependency-injection.md) or a host such as ASP.NET's [WebApplication](/aspnet/core/fundamentals/minimal-apis/webapplication) or [Generic Host](generic-host.md), use `ILoggerFactory` and `ILogger` objects from the DI container rather than creating them directly. ### Get an ILogger from DI @@ -65,14 +65,13 @@ This example gets an ILogger object in a hosted app using [ASP.NET Minimal APIs] The preceding example: - Created a singleton service called `ExampleHandler` and mapped incoming web requests to run the `ExampleHandler.HandleRequest` function. -- Line 12 defines a [primary constructor](../../csharp/whats-new/tutorials/primary-constructors.md) for the ExampleHandler, a feature added in C# 12. Using the older style C# constructor would work equally well but is a little more verbose. +- Line 12 defines a [primary constructor](../../csharp/whats-new/tutorials/primary-constructors.md) for the ExampleHandler, a feature added in C# 12. Using the older style C# constructor works equally well but is a little more verbose. - The constructor defines a parameter of type `ILogger`. derives from and indicates which category the `ILogger` object has. The DI container locates an `ILogger` with the correct category and supplies it as the constructor argument. If no `ILogger` with that category exists yet, the DI container automatically creates it from the `ILoggerFactory` in the service provider. -- The `logger` parameter received in the constructor was used for logging in the `HandleRequest` function. +- The `logger` parameter received in the constructor is used for logging in the `HandleRequest` function. ### Host-provided ILoggerFactory -Host builders initialize [default configuration](generic-host.md#host-builder-settings), -then add a configured `ILoggerFactory` object to the host's DI container when the host is built. Before the host is built you can adjust the logging configuration via , , or similar APIs on other hosts. Hosts also apply logging configuration from default configuration sources as _appsettings.json_ and environment variables. For more information, see [Configuration in .NET](configuration.md). +Host builders initialize [default configuration](generic-host.md#host-builder-settings), then add a configured `ILoggerFactory` object to the host's DI container when the host is built. Before the host is built, adjust the logging configuration via , , or similar APIs on other hosts. Hosts also apply logging configuration from default configuration sources like _appsettings.json_ and environment variables. For more information, see [Configuration in .NET](configuration.md). This example expands on the previous one to customize the `ILoggerFactory` provided by `WebApplicationBuilder`. It adds [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-dotnet#getting-started) as a logging provider transmitting the logs over [OTLP (OpenTelemetry protocol)](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md#enable-log-exporter): @@ -88,16 +87,16 @@ The preceding example: - Created a DI service container containing an `ILoggerFactory` configured to write to the console - Added a singleton `ExampleService` to the container -- Created an instance of the `ExampleService` from the DI container which also automatically created an `ILogger` to use as the constructor argument. -- Invoked `ExampleService.DoSomeWork` which used the `ILogger` to log a message to the console. +- Created an instance of the `ExampleService` from the DI container, which also automatically created an `ILogger` to use as the constructor argument. +- Invoked `ExampleService.DoSomeWork`, which used the `ILogger` to log a message to the console. ## Configure logging -Logging configuration is set in code or via external sources, such as config files and environment variables. Using external configuration is beneficial when possible because it can be changed without rebuilding the application. However, some tasks, such as setting logging providers, can only be configured from code. +Set logging configuration in code or via external sources, such as config files and environment variables. Using external configuration is beneficial when possible because you can change it without rebuilding the application. However, some tasks, such as setting logging providers, can only be configured from code. ### Configure logging without code -For apps that [use a host](#integration-with-hosts-and-dependency-injection), logging configuration is commonly provided by the `"Logging"` section of _appsettings_`.{Environment}`_.json_ files. For apps that don't use a host, external configuration sources are [set up explicitly](configuration.md) or [configured in code](#configure-logging-with-code) instead. +For apps that [use a host](#integration-with-hosts-and-dependency-injection), the `"Logging"` section of _appsettings_`.{Environment}`_.json_ files commonly provides logging configuration. For apps that don't use a host, [set up external configuration sources explicitly](configuration.md) or [configure them in code](#configure-logging-with-code) instead. The following _appsettings.Development.json_ file is generated by the .NET Worker service templates: @@ -106,11 +105,11 @@ The following _appsettings.Development.json_ file is generated by the .NET Worke In the preceding JSON: - The `"Default"`, `"Microsoft"`, and `"Microsoft.Hosting.Lifetime"` log level categories are specified. -- The `"Default"` value is applied to all categories that aren't otherwise specified, effectively making all default values for all categories `"Information"`. You can override this behavior by specifying a value for a category. +- The `"Default"` value applies to all categories that aren't otherwise specified, effectively making all default values for all categories `"Information"`. Override this behavior by specifying a value for a category. - The `"Microsoft"` category applies to all categories that start with `"Microsoft"`. - The `"Microsoft"` category logs at a log level of `Warning` and higher. - The `"Microsoft.Hosting.Lifetime"` category is more specific than the `"Microsoft"` category, so the `"Microsoft.Hosting.Lifetime"` category logs at log level `"Information"` and higher. -- A specific log provider is not specified, so `LogLevel` applies to all the enabled logging providers except for the [Windows EventLog](logging-providers.md#windows-eventlog). +- A specific log provider isn't specified, so `LogLevel` applies to all the enabled logging providers except for the [Windows EventLog](logging-providers.md#windows-eventlog). The `Logging` property can have and log provider properties. The `LogLevel` specifies the minimum [level](#log-level) to log for selected categories. In the preceding JSON, `Information` and `Warning` log levels are specified. `LogLevel` indicates the severity of the log and ranges from 0 to 6: @@ -126,15 +125,15 @@ Settings in `Logging.{ProviderName}.LogLevel` override settings in `Logging.LogL `Logging:Debug:LogLevel:Default:Information` -The preceding setting specifies the `Information` log level for every `Logging:Debug:` category except `Microsoft.Hosting`. When a specific category is listed, the specific category overrides the default category. In the preceding JSON, the `Logging:Debug:LogLevel` categories `"Microsoft.Hosting"` and `"Default"` override the settings in `Logging:LogLevel` +The preceding setting specifies the `Information` log level for every `Logging:Debug:` category except `Microsoft.Hosting`. When a specific category is listed, the specific category overrides the default category. In the preceding JSON, the `Logging:Debug:LogLevel` categories `"Microsoft.Hosting"` and `"Default"` override the settings in `Logging:LogLevel`. -The minimum log level can be specified for any of: +Specify the minimum log level for any of these: - Specific providers: For example, `Logging:EventSource:LogLevel:Default:Information` - Specific categories: For example, `Logging:LogLevel:Microsoft:Warning` - All providers and all categories: `Logging:LogLevel:Default:Warning` -Any logs below the minimum level are ***not***: +Any logs below the minimum level ***aren't***: - Passed to the provider. - Logged or displayed. @@ -149,9 +148,9 @@ The following *appsettings.json* file contains settings for all of the built-in In the preceding sample: -- The categories and levels are not suggested values. The sample is provided to show all the default providers. +- The categories and levels aren't suggested values. The sample shows all the default providers. - Settings in `Logging.{ProviderName}.LogLevel` override settings in `Logging.LogLevel`. For example, the level in `Debug.LogLevel.Default` overrides the level in `LogLevel.Default`. -- Each provider's *alias* is used. Each provider defines an *alias* that can be used in configuration in place of the fully qualified type name. The built-in providers' aliases are: +- Each provider's *alias* is used. Each provider defines an *alias* that you can use in configuration in place of the fully qualified type name. The built-in providers' aliases are: - `Console` - `Debug` - `EventSource` @@ -162,7 +161,7 @@ In the preceding sample: ### Set log level by command line, environment variables, and other configuration -Log level can be set by any of the [configuration providers](configuration-providers.md). For example, you can create a persisted environment variable named `Logging:LogLevel:Microsoft` with a value of `Information`. +Set the log level using any of the [configuration providers](configuration-providers.md). For example, create a persisted environment variable named `Logging:LogLevel:Microsoft` with a value of `Information`. ## [Command Line](#tab/command-line) @@ -215,14 +214,12 @@ echo $Logging__LogLevel__Microsoft # Or use printenv: # printenv Logging__LogLevel__Microsoft -``` - -> [!NOTE] -> When configuring environment variables with names that contain `.` (periods), consider the "Exporting a variable with a dot (.) in it" question on **Stack Exchange** and its corresponding [accepted answer](https://unix.stackexchange.com/a/93533). +```> [!NOTE] +> When configuring environment variables with names that contain `.` (periods), see the "Exporting a variable with a dot (.) in it" question on **Stack Exchange** and its corresponding [accepted answer](https://unix.stackexchange.com/a/93533). --- -The preceding environment setting is persisted in the environment. To test the settings when using an app created with the .NET Worker service templates, use the `dotnet run` command in the project directory after the environment variable is assigned. +The preceding environment setting persists in the environment. To test the settings when using an app created with the .NET Worker service templates, use the `dotnet run` command in the project directory after the environment variable is assigned. ```dotnetcli dotnet run @@ -240,7 +237,7 @@ For more information on setting .NET configuration values using environment vari ### Configure logging with code -To configure logging in code, use the API. This can be accessed from different places: +To configure logging in code, use the API. Access it from different places: - When creating the `ILoggerFactory` directly, configure in . - When using DI without a host, configure in . @@ -264,11 +261,11 @@ ILogger logger = loggerFactory.CreateLogger(); logger.LogDebug("Hello {Target}", "Everyone"); ``` -In the preceding example is used to [adjust the log level](#how-filtering-rules-are-applied) that's enabled for various categories. is used to add the console logging provider. By default, logs with `Debug` severity aren't enabled, but because the configuration adjusted the filters, the debug message "Hello Everyone" is displayed on the console. +In the preceding example, [adjusts the log level](#how-filtering-rules-are-applied) that's enabled for various categories. adds the console logging provider. By default, logs with `Debug` severity aren't enabled, but because the configuration adjusted the filters, the debug message "Hello Everyone" is displayed on the console. ## How filtering rules are applied -When an object is created, the object selects a single rule per provider to apply to that logger. All messages written by an `ILogger` instance are filtered based on the selected rules. The most specific rule for each provider and category pair is selected from the available rules. +When an object is created, the object selects a single rule per provider to apply to that logger. The `ILogger` instance filters all messages it writes based on the selected rules. The most specific rule for each provider and category pair is selected from the available rules. The following algorithm is used for each provider when an `ILogger` is created for a given category: @@ -279,7 +276,7 @@ The following algorithm is used for each provider when an `ILogger` is created f ## Log category -When an `ILogger` object is created, a *category* is specified. That category is included with each log message created by that instance of `ILogger`. The category string is arbitrary, but the convention is to use the fully qualified class name. For example, in an application with a service defined like the following object, the category might be `"Example.DefaultService"`: +When an `ILogger` object is created, a *category* is specified. That category is included with each log message created by that instance of `ILogger`. The category string is arbitrary, but the convention is to use the fully qualified class name. For example, in an application with a service defined like this object, the category might be `"Example.DefaultService"`: ```csharp namespace Example @@ -313,7 +310,7 @@ namespace Example } ``` -Calling `CreateLogger` with a fixed name can be useful when used in multiple classes/types so the events can be organized by category. +Calling `CreateLogger` with a fixed name is useful when used in multiple classes/types so the events can be organized by category. `ILogger` is equivalent to calling `CreateLogger` with the fully qualified type name of `T`. @@ -412,7 +409,7 @@ internal static class AppLogEvents An event ID associates a set of events. For example, all logs related to reading values from a repository might be `1001`. -The logging provider may log the event ID in an ID field, in the logging message, or not at all. The Debug provider doesn't show event IDs. The console provider shows event IDs in brackets after the category: +The logging provider might log the event ID in an ID field, in the logging message, or not at all. The Debug provider doesn't show event IDs. The console provider shows event IDs in brackets after the category: ```console info: Example.DefaultService.GetAsync[1001] @@ -442,7 +439,7 @@ Parameter values: param1, param2 > [!NOTE] > Be mindful when using multiple placeholders within a single message template, as they're ordinal-based. The names are _not_ used to align the arguments to the placeholders. -This approach allows logging providers to implement [semantic or structured logging](https://github.com/NLog/NLog/wiki/How-to-use-structured-logging). The arguments themselves are passed to the logging system, not just the formatted message template. This enables logging providers to store the parameter values as fields. Consider the following logger method: +This approach lets logging providers implement [semantic or structured logging](https://github.com/NLog/NLog/wiki/How-to-use-structured-logging). The arguments themselves are passed to the logging system, not just the formatted message template. This enables logging providers to store the parameter values as fields. Consider this logger method: ```csharp _logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now); @@ -455,7 +452,7 @@ For example, when logging to Azure Table Storage: ### Log message template formatting -Log message templates support placeholder formatting. Templates are free to specify [any valid format](../../standard/base-types/formatting-types.md) for the given type argument. For example, consider the following `Information` logger message template: +Log message templates support placeholder formatting. Templates can specify [any valid format](../../standard/base-types/formatting-types.md) for the given type argument. For example, consider this `Information` logger message template: ```csharp _logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow); @@ -468,7 +465,7 @@ For more information on `DateTime` and `DateTimeOffset` formatting, see [Custom #### Examples -The following examples show how to format a message template using the `{}` placeholder syntax. Additionally, an example of escaping the `{}` placeholder syntax is shown with its output. Finally, string interpolation with templating placeholders is also shown: +These examples show how to format a message template using the `{}` placeholder syntax. Additionally, an example of escaping the `{}` placeholder syntax is shown with its output. Finally, string interpolation with templating placeholders is also shown: ```csharp logger.LogInformation("Number: {Number}", 1); // Number: 1 @@ -508,16 +505,16 @@ Exception logging is provider-specific. ### Default log level -If the default log level is not set, the default log level value is `Information`. +If the default log level isn't set, the default log level value is `Information`. -For example, consider the following worker service app: +For example, consider this worker service app: - Created with the .NET Worker templates. - *appsettings.json* and *appsettings.Development.json* deleted or renamed. With the preceding setup, navigating to the privacy or home page produces many `Trace`, `Debug`, and `Information` messages with `Microsoft` in the category name. -The following code sets the default log level when the default log level is not set in configuration: +The following code sets the default log level when the default log level isn't set in configuration: ```csharp HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); @@ -552,7 +549,7 @@ The preceding code displays console logs when the category contains `Example` or ## Log scopes - A *scope* groups a set of logical operations. This grouping can be used to attach the same data to each log that's created as part of a set. For example, every log created as part of processing a transaction can include the transaction ID. +A *scope* groups a set of logical operations. This grouping can attach the same data to each log that's created as part of a set. For example, every log created as part of processing a transaction can include the transaction ID. A scope: @@ -658,7 +655,7 @@ Logging should be so fast that it isn't worth the performance cost of asynchrono ## Change log levels in a running app -The Logging API doesn't include a scenario to change log levels while an app is running. However, some configuration providers are capable of reloading configuration, which takes immediate effect on logging configuration. For example, the [File Configuration Provider](configuration-providers.md#file-configuration-provider) reloads logging configuration by default. If the configuration is changed in code while an app is running, the app can call [IConfigurationRoot.Reload](xref:Microsoft.Extensions.Configuration.IConfigurationRoot.Reload%2A) to update the app's logging configuration. +The Logging API doesn't include a scenario to change log levels while an app is running. However, some configuration providers can reload configuration, which takes immediate effect on logging configuration. For example, the [File Configuration Provider](configuration-providers.md#file-configuration-provider) reloads logging configuration by default. If the configuration is changed in code while an app is running, the app can call [IConfigurationRoot.Reload](xref:Microsoft.Extensions.Configuration.IConfigurationRoot.Reload%2A) to update the app's logging configuration. ## NuGet packages From e07d9109c3ba6c5324c7e0dfd20f058647053019 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 22:02:42 +0000 Subject: [PATCH 03/30] Apply freshness edits to dependency-injection.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/extensions/dependency-injection.md | 53 ++++++++++---------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md index 88e4007c9f6fb..cb9701da5255f 100644 --- a/docs/core/extensions/dependency-injection.md +++ b/docs/core/extensions/dependency-injection.md @@ -3,15 +3,16 @@ title: Dependency injection description: Learn how to use dependency injection within your .NET apps. Discover how to registration services, define service lifetimes, and express dependencies in C#. author: IEvangelist ms.author: dapine -ms.date: 07/18/2024 +ms.date: 10/21/2025 ms.topic: overview +ai-usage: ai-assisted --- # .NET dependency injection .NET supports the dependency injection (DI) software design pattern, which is a technique for achieving [Inversion of Control (IoC)](../../architecture/modern-web-apps-azure/architectural-principles.md#dependency-inversion) between classes and their dependencies. Dependency injection in .NET is a built-in part of the framework, along with configuration, logging, and the options pattern. -A *dependency* is an object that another object depends on. Examine the following `MessageWriter` class with a `Write` method that other classes depend on: +A *dependency* is an object that another object depends on. Examine this `MessageWriter` class with a `Write` method that other classes depend on: ```csharp public class MessageWriter @@ -23,7 +24,7 @@ public class MessageWriter } ``` -A class can create an instance of the `MessageWriter` class to make use of its `Write` method. In the following example, the `MessageWriter` class is a dependency of the `Worker` class: +A class can create an instance of the `MessageWriter` class to use its `Write` method. In this example, the `MessageWriter` class is a dependency of the `Worker` class: ```csharp public class Worker : BackgroundService @@ -41,16 +42,16 @@ public class Worker : BackgroundService } ``` -The class creates and directly depends on the `MessageWriter` class. Hard-coded dependencies, such as in the previous example, are problematic and should be avoided for the following reasons: +The class creates and directly depends on the `MessageWriter` class. Hard-coded dependencies, such as in the previous example, are problematic and should be avoided for these reasons: -- To replace `MessageWriter` with a different implementation, the `Worker` class must be modified. -- If `MessageWriter` has dependencies, they must also be configured by the `Worker` class. In a large project with multiple classes depending on `MessageWriter`, the configuration code becomes scattered across the app. +- To replace `MessageWriter` with a different implementation, you must modify the `Worker` class. +- If `MessageWriter` has dependencies, the `Worker` class must also configure them. In a large project with multiple classes depending on `MessageWriter`, the configuration code becomes scattered across the app. - This implementation is difficult to unit test. The app should use a mock or stub `MessageWriter` class, which isn't possible with this approach. Dependency injection addresses these problems through: - The use of an interface or base class to abstract the dependency implementation. -- Registration of the dependency in a service container. .NET provides a built-in service container, . Services are typically registered at the app's start-up and appended to an . Once all services are added, you use to create the service container. +- Registration of the dependency in a service container. .NET provides a built-in service container, . Services are typically registered at the app's start-up and appended to an . Once all services are added, use to create the service container. - *Injection* of the service into the constructor of the class where it's used. The framework takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed. As an example, the `IMessageWriter` interface defines the `Write` method: @@ -81,10 +82,10 @@ The host contains the dependency injection service provider. It also contains al By using the DI pattern, the worker service: -- Doesn't use the concrete type `MessageWriter`, only the `IMessageWriter` interface that it implements. That makes it easy to change the implementation that the worker service uses without modifying the worker service. -- Doesn't create an instance of `MessageWriter`. The instance is created by the DI container. +- Doesn't use the concrete type `MessageWriter`, only the `IMessageWriter` interface that it implements. This makes it easy to change the implementation that the worker service uses without modifying the worker service. +- Doesn't create an instance of `MessageWriter`. The DI container creates the instance. -The implementation of the `IMessageWriter` interface can be improved by using the built-in logging API: +The implementation of the `IMessageWriter` interface can be improved using the built-in logging API: :::code language="csharp" source="snippets/configuration/dependency-injection/LoggingMessageWriter.cs"::: @@ -98,16 +99,16 @@ The (`builder`) type `LoggingMessageWriter` depends on , which it requests in the constructor. `ILogger` is a [framework-provided service](#framework-provided-services). -It's not unusual to use dependency injection in a chained fashion. Each requested dependency in turn requests its own dependencies. The container resolves the dependencies in the graph and returns the fully resolved service. The collective set of dependencies that must be resolved is typically referred to as a *dependency tree*, *dependency graph*, or *object graph*. +It's not unusual to use dependency injection in a chained fashion. Each requested dependency in turn requests its own dependencies. The container resolves the dependencies in the graph and returns the fully resolved service. The collective set of dependencies that must be resolved is typically called a *dependency tree*, *dependency graph*, or *object graph*. The container resolves `ILogger` by taking advantage of [(generic) open types](/dotnet/csharp/language-reference/language-specification/types#843-open-and-closed-types), eliminating the need to register every [(generic) constructed type](/dotnet/csharp/language-reference/language-specification/types#84-constructed-types). With dependency injection terminology, a service: - Is typically an object that provides a service to other objects, such as the `IMessageWriter` service. -- Is not related to a web service, although the service may use a web service. +- Isn't related to a web service, although the service might use a web service. -The framework provides a robust logging system. The `IMessageWriter` implementations shown in the preceding examples were written to demonstrate basic DI, not to implement logging. Most apps shouldn't need to write loggers. The following code demonstrates using the default logging, which only requires the `Worker` to be registered as a hosted service : +The framework provides a robust logging system. The `IMessageWriter` implementations shown in the preceding examples demonstrate basic DI, not logging. Most apps shouldn't need to write loggers. The following code demonstrates using the default logging, which only requires the `Worker` to be registered as a hosted service : ```csharp public sealed class Worker(ILogger logger) : BackgroundService @@ -124,7 +125,7 @@ public sealed class Worker(ILogger logger) : BackgroundService } ``` -Using the preceding code, there is no need to update _Program.cs_, because logging is provided by the framework. +Using the preceding code, there's no need to update _Program.cs_, because the framework provides logging. ## Multiple constructor discovery rules @@ -149,9 +150,9 @@ public class ExampleService } ``` -In the preceding code, assume that logging has been added and is resolvable from the service provider but the `FooService` and `BarService` types are not. The constructor with the `ILogger` parameter is used to resolve the `ExampleService` instance. Even though there's a constructor that defines more parameters, the `FooService` and `BarService` types are not DI-resolvable. +In the preceding code, assume that logging has been added and is resolvable from the service provider but the `FooService` and `BarService` types aren't. The constructor with the `ILogger` parameter resolves the `ExampleService` instance. Even though there's a constructor that defines more parameters, the `FooService` and `BarService` types aren't DI-resolvable. -If there's ambiguity when discovering constructors, an exception is thrown. Consider the following C# example service: +If there's ambiguity when discovering constructors, an exception is thrown. Consider this C# example service: ```csharp public class ExampleService @@ -175,9 +176,9 @@ public class ExampleService > [!WARNING] > The `ExampleService` code with ambiguous DI-resolvable type parameters would throw an exception. Do **not** do this—it's intended to show what is meant by "ambiguous DI-resolvable types". -In the preceding example, there are three constructors. The first constructor is parameterless and requires no services from the service provider. Assume that both logging and options have been added to the DI container and are DI-resolvable services. When the DI container attempts to resolve the `ExampleService` type, it will throw an exception, as the two constructors are ambiguous. +In the preceding example, there are three constructors. The first constructor is parameterless and requires no services from the service provider. Assume that both logging and options have been added to the DI container and are DI-resolvable services. When the DI container attempts to resolve the `ExampleService` type, it throws an exception, as the two constructors are ambiguous. -You can avoid ambiguity by defining a constructor that accepts both DI-resolvable types instead: +Avoid ambiguity by defining a constructor that accepts both DI-resolvable types instead: ```csharp public class ExampleService @@ -210,7 +211,7 @@ When using any of the available host or app builder patterns, defaults are appli - - -After creating a builder from any of these APIs, the `IServiceCollection` has services defined by the framework, depending on [how the host was configured](generic-host.md#host-configuration). For apps based on the .NET templates, the framework could register hundreds of services. +After creating a builder from any of these APIs, the `IServiceCollection` has services defined by the framework, depending on [how you configured the host](generic-host.md#host-configuration). For apps based on the .NET templates, the framework could register hundreds of services. The following table lists a small sample of these framework-registered services: @@ -303,7 +304,7 @@ This is equivalent to registering the service with both the service and implemen services.AddSingleton(); ``` -This equivalency is why multiple implementations of a service can't be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they will all have the same *implementation* type. +This equivalency is why multiple implementations of a service can't be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they all have the same *implementation* type. Any of the above service registration methods can be used to register multiple service instances of the same service type. In the following example, `AddSingleton` is called twice with `IMessageWriter` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMessageWriter` and adds to the previous one when multiple services are resolved via `IEnumerable`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`. @@ -324,7 +325,7 @@ services.AddSingleton(); services.TryAddSingleton(); ``` -The `TryAddSingleton` has no effect, as it was already added and the "try" will fail. The `ExampleService` would assert the following: +The `TryAddSingleton` has no effect, as it was already added and the "try" fails. The `ExampleService` would assert this: ```csharp public class ExampleService @@ -348,7 +349,7 @@ For more information, see: The [TryAddEnumerable(ServiceDescriptor)](xref:Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddEnumerable%2A) methods register the service only if there isn't already an implementation *of the same type*. Multiple services are resolved via `IEnumerable<{SERVICE}>`. When registering services, add an instance if one of the same types hasn't already been added. Library authors use `TryAddEnumerable` to avoid registering multiple copies of an implementation in the container. -In the following example, the first call to `TryAddEnumerable` registers `MessageWriter` as an implementation for `IMessageWriter1`. The second call registers `MessageWriter` for `IMessageWriter2`. The third call has no effect because `IMessageWriter1` already has a registered implementation of `MessageWriter`: +In this example, the first call to `TryAddEnumerable` registers `MessageWriter` as an implementation for `IMessageWriter1`. The second call registers `MessageWriter` for `IMessageWriter2`. The third call has no effect because `IMessageWriter1` already has a registered implementation of `MessageWriter`: ```csharp public interface IMessageWriter1 { } @@ -365,7 +366,7 @@ services.TryAddEnumerable(ServiceDescriptor.Singleton objects. The following example shows how to register a service by creating and adding a `ServiceDescriptor`: +`IServiceCollection` is a collection of objects. This example shows how to register a service by creating and adding a `ServiceDescriptor`: ```csharp string secretKey = Configuration["SecretKey"]; @@ -381,7 +382,7 @@ The built-in `Add{LIFETIME}` methods use the same approach. For example, see the ### Constructor injection behavior -Services can be resolved by using: +Services can be resolved using: - - : @@ -409,7 +410,7 @@ Scoped services are disposed by the container that created them. If a scoped ser The is always registered as a singleton, but the can vary based on the lifetime of the containing class. For example, if you resolve services from a scope, and any of those services take an , it'll be a scoped instance. -To achieve scoping services within implementations of , such as the , do *not* inject the service dependencies via constructor injection. Instead, inject , create a scope, then resolve dependencies from the scope to use the appropriate service lifetime. +To achieve scoping services within implementations of , such as the , *don't* inject the service dependencies via constructor injection. Instead, inject , create a scope, then resolve dependencies from the scope to use the appropriate service lifetime. :::code language="csharp" source="snippets/configuration/worker-scope/Worker.cs"::: @@ -424,7 +425,7 @@ From the sample source code, you can see how implementations of Date: Tue, 21 Oct 2025 22:05:00 +0000 Subject: [PATCH 04/30] Apply freshness edits to tutorials/index.md and get-started.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/get-started.md | 9 +++++---- docs/core/tutorials/index.md | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/core/get-started.md b/docs/core/get-started.md index e9c5a16575ecb..b97df25ed41c2 100644 --- a/docs/core/get-started.md +++ b/docs/core/get-started.md @@ -3,9 +3,10 @@ title: Get started with .NET description: Create a Hello World .NET app. author: adegeo ms.author: adegeo -ms.date: 07/19/2022 +ms.date: 10/21/2025 ms.custom: vs-dotnet, devdivchpfy22 ms.topic: tutorial +ai-usage: ai-assisted --- # Get started with .NET @@ -17,7 +18,7 @@ First, download and install the [.NET SDK](https://dotnet.microsoft.com/download Next, open a terminal such as **PowerShell**, **Command Prompt**, or **bash**. -Type the following commands: +Type these commands: ```dotnetcli dotnet new console -o sample1 @@ -25,7 +26,7 @@ cd sample1 dotnet run ``` -You should see the following output: +You should see this output: ```output Hello World! @@ -35,4 +36,4 @@ Congratulations! You've created a simple .NET application. ## Next steps -Get started on developing .NET applications by following a [step-by-step tutorial](../standard/get-started.md) or by watching [.NET 101 videos](https://www.youtube.com/playlist?list=PLdo4fOcmZ0oWoazjhXQzBKMrFuArxpW80) on YouTube. +Get started developing .NET applications by following a [step-by-step tutorial](../standard/get-started.md) or by watching [.NET 101 videos](https://www.youtube.com/playlist?list=PLdo4fOcmZ0oWoazjhXQzBKMrFuArxpW80) on YouTube. diff --git a/docs/core/tutorials/index.md b/docs/core/tutorials/index.md index b197764e75836..cbeb2a23c26ad 100644 --- a/docs/core/tutorials/index.md +++ b/docs/core/tutorials/index.md @@ -1,13 +1,14 @@ --- title: .NET Tutorials description: Follow tutorials for learning .NET to build apps and libraries on Mac, Linux, and Windows. -ms.date: 06/22/2022 +ms.date: 10/21/2025 ms.custom: devdivchpfy22 titleSuffix: "" +ai-usage: ai-assisted --- # Learn .NET and the .NET SDK tools by exploring these tutorials -The following tutorials show how to develop console apps and libraries for .NET Core, .NET 5, and later versions. For other types of applications, see [Tutorials for getting started with .NET](../../standard/get-started.md). +These tutorials show how to develop console apps and libraries for .NET Core, .NET 5, and later versions. For other types of applications, see [Tutorials for getting started with .NET](../../standard/get-started.md). ## Use Visual Studio @@ -22,7 +23,7 @@ The following tutorials show how to develop console apps and libraries for .NET ## Use Visual Studio Code -Choose these tutorials if you want to use Visual Studio Code or some other code editor. All of them use the CLI for .NET Core development tasks, so all except the debugging tutorial can be used with any code editor. +Choose these tutorials if you want to use Visual Studio Code or another code editor. All of them use the CLI for .NET Core development tasks, so all except the debugging tutorial can be used with any code editor. - [Create a console app](with-visual-studio-code.md) - [Debug an app](debugging-with-visual-studio-code.md) From f7ed95887ba592ef9b9a079e8352f921b1303998 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 22:07:37 +0000 Subject: [PATCH 05/30] Apply freshness edits to clr.md and commandline/index.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/standard/clr.md | 9 +++++---- docs/standard/commandline/index.md | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/standard/clr.md b/docs/standard/clr.md index 19a5723ec231b..a06ab205d7eac 100644 --- a/docs/standard/clr.md +++ b/docs/standard/clr.md @@ -2,7 +2,7 @@ title: "Common Language Runtime (CLR) overview - .NET" titleSuffix: "" description: Get started with common language runtime (CLR), .NET's run-time environment. The CLR runs code and provides services to make the development process easier. -ms.date: 07/26/2022 +ms.date: 10/21/2025 ms.custom: devdivchpfy22 helpviewer_keywords: - "compiling source code, runtime functionality" @@ -17,6 +17,7 @@ helpviewer_keywords: - "source code execution" - "code, runtime functionality" ms.assetid: 059a624e-f7db-4134-ba9f-08b676050482 +ai-usage: ai-assisted --- # Common Language Runtime (CLR) overview @@ -29,13 +30,13 @@ Compilers and tools expose the common language runtime's functionality and enabl To enable the runtime to provide services to managed code, language compilers must emit metadata that describes the types, members, and references in your code. Metadata is stored with the code; every loadable common language runtime portable executable (PE) file contains metadata. The runtime uses metadata to locate and load classes, lay out instances in memory, resolve method invocations, generate native code, enforce security, and set run-time context boundaries. -The runtime automatically handles object layout and manages references to objects, releasing them when they're no longer being used. Objects whose lifetimes are managed in this way are called managed data. Garbage collection eliminates memory leaks and some other common programming errors. If your code is managed, you can use managed, unmanaged, or both managed and unmanaged data in your .NET application. Because language compilers supply their own types, such as primitive types, you might not always know or need to know whether your data is being managed. +The runtime automatically handles object layout and manages references to objects, releasing them when they're no longer being used. Objects whose lifetimes are managed this way are called managed data. Garbage collection eliminates memory leaks and some other common programming errors. If your code is managed, you can use managed data, unmanaged data, or both in your .NET application. Because language compilers supply their own types, such as primitive types, you might not always know or need to know whether your data is being managed. The common language runtime makes it easy to design components and applications whose objects interact across languages. Objects written in different languages can communicate with each other, and their behaviors can be tightly integrated. For example, you can define a class and then use a different language to derive a class from your original class or call a method on the original class. You can also pass an instance of a class to a method of a class written in a different language. This cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime. They follow the runtime's rules for defining new types and for creating, using, persisting, and binding to types. As part of their metadata, all managed components carry information about the components and resources they were built against. The runtime uses this information to ensure that your component or application has the specified versions of everything it needs, which makes your code less likely to break because of some unmet dependency. Registration information and state data are no longer stored in the registry, where they can be difficult to establish and maintain. Instead, information about the types you define and their dependencies is stored with the code as metadata. This way, the task of component replication and removal is less complicated. -Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. Some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you're a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before. The runtime provides the following benefits: +Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. Some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you're a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before. The runtime provides these benefits: - Performance improvements. @@ -59,7 +60,7 @@ Language compilers and tools expose the runtime's functionality in ways that are .NET Core and .NET 5+ releases have a single product version, that is, there's no separate CLR version. For a list of .NET Core versions, see [Download .NET Core](https://dotnet.microsoft.com/download/dotnet). -However, the .NET Framework version number doesn't necessarily correspond to the version number of the CLR it includes. For a list of .NET Framework versions and their corresponding CLR versions, see [.NET Framework versions and dependencies](../framework/install/versions-and-dependencies.md). +However, .NET Framework version number doesn't necessarily correspond to the version number of the CLR it includes. For a list of .NET Framework versions and their corresponding CLR versions, see [.NET Framework versions and dependencies](../framework/install/versions-and-dependencies.md). ## Related articles diff --git a/docs/standard/commandline/index.md b/docs/standard/commandline/index.md index 3ca349aa188c6..c1105328bf4ba 100644 --- a/docs/standard/commandline/index.md +++ b/docs/standard/commandline/index.md @@ -1,13 +1,14 @@ --- title: System.CommandLine overview description: "Learn how to develop and use command-line apps that are based on the System.CommandLine library." -ms.date: 04/07/2022 +ms.date: 10/21/2025 no-loc: [System.CommandLine] helpviewer_keywords: - "command line interface" - "command line" - "System.CommandLine" ms.topic: overview +ai-usage: ai-assisted --- # System.CommandLine overview @@ -35,12 +36,12 @@ The library is available as a NuGet package: [System.CommandLine](https://www.nu ## Next steps -To get started with System.CommandLine, see the following resources: +To get started with System.CommandLine, see these resources: - [Tutorial: Get started with System.CommandLine](get-started-tutorial.md) - [Syntax overview: commands, options, and arguments](syntax.md) -To learn more, see the following resources: +To learn more, see these resources: - [How to parse and invoke the result](how-to-parse-and-invoke.md) - [How to customize parsing and validation](how-to-customize-parsing-and-validation.md) From f19c105ed4904c160ca29ad13c36d79cab88a07b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 22:13:12 +0000 Subject: [PATCH 06/30] Apply freshness edits to collections/thread-safe/index.md and io/how-to-write-text-to-a-file.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/standard/collections/thread-safe/index.md | 7 ++++--- docs/standard/io/how-to-write-text-to-a-file.md | 13 +++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/standard/collections/thread-safe/index.md b/docs/standard/collections/thread-safe/index.md index 19205829cac68..d0b35b0f9f108 100644 --- a/docs/standard/collections/thread-safe/index.md +++ b/docs/standard/collections/thread-safe/index.md @@ -1,14 +1,15 @@ --- title: Thread-Safe collections description: Get started with thread-safe collections using the System.Collections.Concurrent namespace in .NET, which includes thread-safe and scalable collection classes. -ms.date: 01/23/2023 +ms.date: 10/21/2025 ms.custom: devdivchpfy22 helpviewer_keywords: - "thread-safe collections, overview" +ai-usage: ai-assisted --- # Thread-safe collections -The namespace includes several collection classes that are both thread-safe and scalable. Multiple threads can safely and efficiently add or remove items from these collections, without requiring additional synchronization in user code. When you write new code, use the concurrent collection classes to write multiple threads to the collection concurrently. If you're only reading from a shared collection, then you can use the classes in the namespace. +The namespace includes several collection classes that are both thread-safe and scalable. Multiple threads can safely and efficiently add or remove items from these collections, without requiring additional synchronization in user code. When you write new code, use the concurrent collection classes to write multiple threads to the collection concurrently. If you're only reading from a shared collection, use the classes in the namespace. ## System.Collections and System.Collections.Generic @@ -27,7 +28,7 @@ The namespace > [!NOTE] > Because the concurrent collections classes support , they provide implementations for the and properties, even though these properties are irrelevant. `IsSynchronized` always returns `false` and, `SyncRoot` is always `null` (`Nothing` in Visual Basic). - The following table lists the collection types in the namespace: +The following table lists the collection types in the namespace: |Type|Description| |----------|-----------------| diff --git a/docs/standard/io/how-to-write-text-to-a-file.md b/docs/standard/io/how-to-write-text-to-a-file.md index c99285060ca97..2d86130006b44 100644 --- a/docs/standard/io/how-to-write-text-to-a-file.md +++ b/docs/standard/io/how-to-write-text-to-a-file.md @@ -1,7 +1,7 @@ --- title: "How to: Write text to a file" description: Learn ways to write or append text to a file for a .NET app. Use methods from the StreamWriter or File classes to write text synchronously or asynchronously. -ms.date: "03/15/2024" +ms.date: "10/21/2025" ms.custom: devdivchpfy22 dev_langs: - "csharp" @@ -12,12 +12,13 @@ helpviewer_keywords: - "streams, writing text to files" - "data streams, writing text to files" ms.assetid: 060cbe06-2adf-4337-9e7b-961a5c840208 +ai-usage: ai-assisted --- # How to: Write text to a file This article shows different ways to write text to a file for a .NET app. -The following classes and methods are typically used to write text to a file: +These classes and methods are typically used to write text to a file: - contains methods to write to a file synchronously ( and ) or asynchronously ( and ). @@ -30,28 +31,28 @@ The following classes and methods are typically used to write text to a file: ## Example: Synchronously write text with StreamWriter -The following example shows how to use the class to synchronously write text to a new file one line at a time. Because the object is declared and instantiated in a `using` statement, the method is invoked, which automatically flushes and closes the stream. +This example shows how to use the class to synchronously write text to a new file one line at a time. Because the object is declared and instantiated in a `using` statement, the method is invoked, which automatically flushes and closes the stream. [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/write.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/write.vb)] ## Example: Synchronously append text with StreamWriter -The following example shows how to use the class to synchronously append text to the text file created in the first example: +This example shows how to use the class to synchronously append text to the text file created in the first example: [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/append.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/append.vb)] ## Example: Asynchronously write text with StreamWriter -The following example shows how to asynchronously write text to a new file using the class. To invoke the method, the method call must be within an `async` method. +This example shows how to asynchronously write text to a new file using the class. To invoke the method, the method call must be within an `async` method. [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/async.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/async.vb)] ## Example: Write and append text with the File class -The following example shows how to write text to a new file and append new lines of text to the same file using the class. The and methods open and close the file automatically. If the path you provide to the method already exists, the file is overwritten. +This example shows how to write text to a new file and append new lines of text to the same file using the class. The and methods open and close the file automatically. If the path you provide to the method already exists, the file is overwritten. [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/file.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/file.vb)] From 3d634e5a67c42c0bd0d4cf2336362f7580182fcf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Oct 2025 22:15:35 +0000 Subject: [PATCH 07/30] Apply freshness edits to assembly/index.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/standard/assembly/index.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/standard/assembly/index.md b/docs/standard/assembly/index.md index f302523881a76..70b41d7ac8185 100644 --- a/docs/standard/assembly/index.md +++ b/docs/standard/assembly/index.md @@ -1,7 +1,7 @@ --- title: "Assemblies in .NET" description: Assemblies are fundamental units of deployment, version control, reuse, activation scoping, and security permissions for .NET-based applications. -ms.date: 07/27/2022 +ms.date: 10/21/2025 ms.custom: devdivchpfy22 ms.assetid: 149f5ca5-5b34-4746-9542-1ae43b2d0256 helpviewer_keywords: @@ -14,6 +14,7 @@ helpviewer_keywords: - "assemblies [.NET Framework]" - "version boundaries" - "type boundaries" +ai-usage: ai-assisted --- # Assemblies in .NET @@ -26,13 +27,13 @@ Assemblies have the following properties: - Assemblies are implemented as *.exe* or *.dll* files. -- For libraries that target .NET Framework, you can share assemblies between applications by putting them in the [global assembly cache (GAC)](../../framework/app-domains/gac.md). You must strong-name assemblies before you can include them in the GAC. For more information, see [Strong-named assemblies](strong-named.md). +- For libraries that target .NET Framework, you can share assemblies between applications by putting them in the [global assembly cache (GAC)](../../framework/app-domains/gac.md). Strong-name assemblies before you can include them in the GAC. For more information, see [Strong-named assemblies](strong-named.md). - Assemblies are only loaded into memory if they're required. If they aren't used, they aren't loaded. Therefore, assemblies can be an efficient way to manage resources in larger projects. -- You can programmatically obtain information about an assembly by using reflection. For more information, see [Reflection (C#)](../../csharp/advanced-topics/reflection-and-attributes/index.md) or [Reflection (Visual Basic)](../../visual-basic/programming-guide/concepts/reflection.md). +- You can programmatically obtain information about an assembly using reflection. For more information, see [Reflection (C#)](../../csharp/advanced-topics/reflection-and-attributes/index.md) or [Reflection (Visual Basic)](../../visual-basic/programming-guide/concepts/reflection.md). -- You can load an assembly just to inspect it by using the class on .NET and .NET Framework. replaces the methods. +- You can load an assembly just to inspect it using the class on .NET and .NET Framework. replaces the methods. ## Assemblies in the common language runtime @@ -56,7 +57,7 @@ An assembly defines the following information: ## Create an assembly -Assemblies can be static or dynamic. Static assemblies are stored on a disk in portable executable (PE) files. Static assemblies can include interfaces, classes, and resources like bitmaps, JPEG files, and other resource files. You can also create dynamic assemblies, which are run directly from memory and aren't saved to disk before execution. You can save dynamic assemblies to disk after they've been executed. +Assemblies can be static or dynamic. Static assemblies are stored on a disk in portable executable (PE) files. Static assemblies can include interfaces, classes, and resources like bitmaps, JPEG files, and other resource files. You can also create dynamic assemblies, which run directly from memory and aren't saved to disk before execution. You can save dynamic assemblies to disk after they've been executed. There are several ways to create assemblies. You can use development tools, such as Visual Studio that can create *.dll* or *.exe* files. You can use tools in the Windows SDK to create assemblies with modules from other development environments. You can also use common language runtime APIs, such as , to create dynamic assemblies. @@ -82,10 +83,10 @@ Assemblies contain information about content, versioning, and dependencies. So t To use an assembly in an application, you must add a reference to it. When an assembly is referenced, all the accessible types, properties, methods, and other members of its namespaces are available to your application as if their code were part of your source file. > [!NOTE] -> Most assemblies from the .NET Class Library are referenced automatically. If a system assembly isn't automatically referenced, add a reference in one of the following ways: +> Most assemblies from the .NET Class Library are referenced automatically. If a system assembly isn't automatically referenced, add a reference in one of these ways: > > - For .NET and .NET Core, add a reference to the NuGet package that contains the assembly. Either use the NuGet Package Manager in Visual Studio or add a [\](../../core/tools/dependencies.md#the-packagereference-element) element for the assembly to the *.csproj* or *.vbproj* project. -> - For .NET Framework, add a reference to the assembly by using the **Add Reference** dialog in Visual Studio or the `-reference` command line option for the [C#](../../csharp/language-reference/compiler-options/inputs.md#references) or [Visual Basic](../../visual-basic/reference/command-line-compiler/reference.md) compilers. +> - For .NET Framework, add a reference to the assembly using the **Add Reference** dialog in Visual Studio or the `-reference` command line option for the [C#](../../csharp/language-reference/compiler-options/inputs.md#references) or [Visual Basic](../../visual-basic/reference/command-line-compiler/reference.md) compilers. In C#, you can use two versions of the same assembly in a single application. For more information, see [extern alias](../../csharp/language-reference/keywords/extern-alias.md). From 58e8532a994f398acfb7d6898a0ef25eeccd7921 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:29:24 +0000 Subject: [PATCH 08/30] Apply freshness edits to task-parallel-library-tpl.md, httpclient-guidelines.md, and socket-services.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- .../networking/http/httpclient-guidelines.md | 7 ++++--- docs/fundamentals/networking/sockets/socket-services.md | 3 ++- .../parallel-programming/task-parallel-library-tpl.md | 9 +++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/fundamentals/networking/http/httpclient-guidelines.md b/docs/fundamentals/networking/http/httpclient-guidelines.md index bb610ac8cad6f..aaeda8a37310e 100644 --- a/docs/fundamentals/networking/http/httpclient-guidelines.md +++ b/docs/fundamentals/networking/http/httpclient-guidelines.md @@ -3,7 +3,8 @@ title: HttpClient guidelines for .NET description: Learn about using HttpClient instances to send HTTP requests and how you can manage clients using IHttpClientFactory in your .NET apps. author: gewarren ms.author: gewarren -ms.date: 03/08/2024 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Guidelines for using HttpClient @@ -12,7 +13,7 @@ The class sends HTTP ## DNS behavior - only resolves DNS entries when a connection is created. It does not track any time to live (TTL) durations specified by the DNS server. If DNS entries change regularly, which can happen in some scenarios, the client won't respect those updates. To solve this issue, you can limit the lifetime of the connection by setting the property, so that DNS lookup is repeated when the connection is replaced. Consider the following example: + only resolves DNS entries when a connection is created. It doesn't track any time to live (TTL) durations specified by the DNS server. If DNS entries change regularly, which can happen in some scenarios, the client won't respect those updates. To solve this issue, limit the lifetime of the connection by setting the property, so that DNS lookup is repeated when the connection is replaced. Consider this example: ```csharp var handler = new SocketsHttpHandler @@ -22,7 +23,7 @@ var handler = new SocketsHttpHandler var sharedClient = new HttpClient(handler); ``` -The preceding `HttpClient` is configured to reuse connections for 15 minutes. After the timespan specified by has elapsed and the connection has completed its last associated request (if any), this connection is closed. If there are any requests waiting in the queue, a new connection is created as needed. +The preceding `HttpClient` is configured to reuse connections for 15 minutes. After the timespan specified by has elapsed and the connection has completed its last associated request (if any), the connection is closed. If there are any requests waiting in the queue, a new connection is created as needed. The 15-minute interval was chosen arbitrarily for illustration purposes. You should choose the value based on the expected frequency of DNS or other network changes. diff --git a/docs/fundamentals/networking/sockets/socket-services.md b/docs/fundamentals/networking/sockets/socket-services.md index 7397fc3dedeb4..0681ff39900d5 100644 --- a/docs/fundamentals/networking/sockets/socket-services.md +++ b/docs/fundamentals/networking/sockets/socket-services.md @@ -3,7 +3,7 @@ title: Use Sockets to send and receive data over TCP description: Learn how the Socket class exposes socket network communication functionality in .NET. author: IEvangelist ms.author: dapine -ms.date: 11/30/2022 +ms.date: 10/22/2025 helpviewer_keywords: - "application protocols, sockets" - "sending data, sockets" @@ -16,6 +16,7 @@ helpviewer_keywords: - "protocols, sockets" - "Internet, sockets" - "client sockets" +ai-usage: ai-assisted --- # Use Sockets to send and receive data over TCP diff --git a/docs/standard/parallel-programming/task-parallel-library-tpl.md b/docs/standard/parallel-programming/task-parallel-library-tpl.md index ca6d68a258d46..fcf377955c499 100644 --- a/docs/standard/parallel-programming/task-parallel-library-tpl.md +++ b/docs/standard/parallel-programming/task-parallel-library-tpl.md @@ -1,19 +1,20 @@ --- title: "Task Parallel Library (TPL)" description: Explore the Task Parallel Library (TPL), a set of public types and APIs to simplify the process of adding parallelism & concurrency to applications in .NET. -ms.date: "08/01/2022" +ms.date: "10/22/2025" ms.custom: devdivchpfy22 helpviewer_keywords: - ".NET, concurrency in" - ".NET, parallel programming in" - "Parallel Programming" ms.assetid: b8f99f43-9104-45fd-9bff-385a20488a23 +ai-usage: ai-assisted --- # Task Parallel Library (TPL) -The Task Parallel Library (TPL) is a set of public types and APIs in the and namespaces. The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism and concurrency to applications. The TPL dynamically scales the degree of concurrency to use all the available processors most efficiently. In addition, the TPL handles the partitioning of the work, the scheduling of threads on the , cancellation support, state management, and other low-level details. By using TPL, you can maximize the performance of your code while focusing on the work that your program is designed to accomplish. - - In .NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code. However, not all code is suitable for parallelization. For example, if a loop performs only a small amount of work on each iteration, or it doesn't run for many iterations, then the overhead of parallelization can cause the code to run more slowly. Furthermore, parallelization, like any multithreaded code, adds complexity to your program execution. Although the TPL simplifies multithreaded scenarios, we recommend that you have a basic understanding of threading concepts, for example, locks, deadlocks, and race conditions, so that you can use the TPL effectively. +The Task Parallel Library (TPL) is a set of public types and APIs in the and namespaces. The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism and concurrency to applications. The TPL dynamically scales the degree of concurrency to use all the available processors most efficiently. In addition, the TPL handles the partitioning of the work, the scheduling of threads on the , cancellation support, state management, and other low-level details. Using TPL, you can maximize the performance of your code while focusing on the work that your program is designed to accomplish. + +In .NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code. However, not all code is suitable for parallelization. For example, if a loop performs only a small amount of work on each iteration, or it doesn't run for many iterations, then the overhead of parallelization can cause the code to run more slowly. Furthermore, parallelization, like any multithreaded code, adds complexity to your program execution. Although the TPL simplifies multithreaded scenarios, we recommend that you have a basic understanding of threading concepts, for example, locks, deadlocks, and race conditions, so that you can use the TPL effectively. ## Related articles From 719003c62535cdae4ce3914912706c19e8321790 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:31:24 +0000 Subject: [PATCH 09/30] Apply freshness edits to ignore-properties.md, testing/index.md, dependency-injection-usage.md, and regular-expressions.md Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/extensions/dependency-injection-usage.md | 3 ++- docs/core/testing/index.md | 3 ++- docs/standard/base-types/regular-expressions.md | 3 ++- .../serialization/system-text-json/ignore-properties.md | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/core/extensions/dependency-injection-usage.md b/docs/core/extensions/dependency-injection-usage.md index 10bd8ef219f79..6c1b23a1e9e32 100644 --- a/docs/core/extensions/dependency-injection-usage.md +++ b/docs/core/extensions/dependency-injection-usage.md @@ -3,9 +3,10 @@ title: Use dependency injection description: Learn how to use dependency injection in your .NET apps with this comprehensive tutorial. Follow along with this pragmatic guide to understand DI in C#. author: IEvangelist ms.author: dapine -ms.date: 07/18/2024 +ms.date: 10/22/2025 ms.topic: tutorial no-loc: [Transient, Scoped, Singleton, Example] +ai-usage: ai-assisted --- # Tutorial: Use dependency injection in .NET diff --git a/docs/core/testing/index.md b/docs/core/testing/index.md index 27060a7c1ca5c..ce1cc9db5ccea 100644 --- a/docs/core/testing/index.md +++ b/docs/core/testing/index.md @@ -3,8 +3,9 @@ title: Testing in .NET description: This article gives a brief overview of testing concepts, terminology, and tools for testing in .NET. author: IEvangelist ms.author: dapine -ms.date: 12/15/2023 +ms.date: 10/22/2025 ms.custom: devdivchpfy22 +ai-usage: ai-assisted --- # Testing in .NET diff --git a/docs/standard/base-types/regular-expressions.md b/docs/standard/base-types/regular-expressions.md index d23bb6d9c1275..659b176034d24 100644 --- a/docs/standard/base-types/regular-expressions.md +++ b/docs/standard/base-types/regular-expressions.md @@ -2,7 +2,7 @@ title: ".NET Regular Expressions" description: Use regular expressions to find specific character patterns, validate text, work with text substrings, & add extracted strings to a collection in .NET. ms.topic: concept-article -ms.date: "07/26/2022" +ms.date: "10/22/2025" ms.custom: devdivchpfy22 dev_langs: - "csharp" @@ -22,6 +22,7 @@ helpviewer_keywords: - ".NET regular expressions" - "strings [.NET], regular expressions" ms.assetid: 521b3f6d-f869-42e1-93e5-158c54a6895d +ai-usage: ai-assisted --- # .NET regular expressions diff --git a/docs/standard/serialization/system-text-json/ignore-properties.md b/docs/standard/serialization/system-text-json/ignore-properties.md index 4900b3f7dc4ad..ed4d8c2c2718e 100644 --- a/docs/standard/serialization/system-text-json/ignore-properties.md +++ b/docs/standard/serialization/system-text-json/ignore-properties.md @@ -1,7 +1,7 @@ --- title: How to ignore properties with System.Text.Json description: "Learn how to ignore properties when serializing with System.Text.Json in .NET." -ms.date: 07/22/2022 +ms.date: 10/22/2025 ms.custom: devdivchpfy22 no-loc: [System.Text.Json, Newtonsoft.Json] dev_langs: @@ -13,6 +13,7 @@ helpviewer_keywords: - "serialization" - "objects, serializing" ms.topic: how-to +ai-usage: ai-assisted --- # How to ignore properties with System.Text.Json From ec77bdd400ddd5d48f11661f87b660b4bafb0233 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:34:17 +0000 Subject: [PATCH 10/30] Complete freshness pass for all core/extensions articles Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/extensions/caching.md | 3 ++- docs/core/extensions/channels.md | 3 ++- docs/core/extensions/dependency-injection-guidelines.md | 3 ++- docs/core/extensions/logger-message-generator.md | 3 ++- docs/core/extensions/logging-providers.md | 3 ++- docs/core/extensions/options.md | 3 ++- docs/core/extensions/windows-service.md | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/core/extensions/caching.md b/docs/core/extensions/caching.md index ec8ff63563179..6394a66daff06 100644 --- a/docs/core/extensions/caching.md +++ b/docs/core/extensions/caching.md @@ -3,7 +3,8 @@ title: Caching in .NET description: Discover effective ways to implement in-memory and distributed caching in .NET. Boost app performance and scalability with .NET caching. author: IEvangelist ms.author: dapine -ms.date: 04/11/2024 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Caching in .NET diff --git a/docs/core/extensions/channels.md b/docs/core/extensions/channels.md index b46af3914801c..21d09a4d211c5 100644 --- a/docs/core/extensions/channels.md +++ b/docs/core/extensions/channels.md @@ -3,7 +3,8 @@ title: Channels description: Learn the official synchronization data structures in System.Threading.Channels for producers and consumers with .NET. author: IEvangelist ms.author: dapine -ms.date: 06/26/2023 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # System.Threading.Channels library diff --git a/docs/core/extensions/dependency-injection-guidelines.md b/docs/core/extensions/dependency-injection-guidelines.md index 91cae91385e2b..460862b1cb631 100644 --- a/docs/core/extensions/dependency-injection-guidelines.md +++ b/docs/core/extensions/dependency-injection-guidelines.md @@ -3,8 +3,9 @@ title: Dependency injection guidelines description: Discover effective dependency injection guidelines and best practices for developing .NET apps. Deepen your understanding of inversion of control. author: IEvangelist ms.author: dapine -ms.date: 07/18/2024 +ms.date: 10/22/2025 ms.topic: concept-article +ai-usage: ai-assisted --- # Dependency injection guidelines diff --git a/docs/core/extensions/logger-message-generator.md b/docs/core/extensions/logger-message-generator.md index 0563a90464400..45e960ca4b479 100644 --- a/docs/core/extensions/logger-message-generator.md +++ b/docs/core/extensions/logger-message-generator.md @@ -1,7 +1,8 @@ --- title: Compile-time logging source generation description: Learn how to use the LoggerMessageAttribute and compile-time source generation for logging in .NET. -ms.date: 06/21/2024 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Compile-time logging source generation diff --git a/docs/core/extensions/logging-providers.md b/docs/core/extensions/logging-providers.md index db4139b014ea4..0bff4f69bc311 100644 --- a/docs/core/extensions/logging-providers.md +++ b/docs/core/extensions/logging-providers.md @@ -3,7 +3,8 @@ title: Logging providers description: Learn how the logging provider API is used in .NET applications. author: IEvangelist ms.author: dapine -ms.date: 06/23/2023 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Logging providers in .NET diff --git a/docs/core/extensions/options.md b/docs/core/extensions/options.md index 71f32116ed1b8..b50ecee4ac147 100644 --- a/docs/core/extensions/options.md +++ b/docs/core/extensions/options.md @@ -3,7 +3,8 @@ title: Options pattern author: IEvangelist description: Learn the options pattern to represent groups of related settings in .NET apps. The options pattern uses classes to provide strongly-typed access to settings. ms.author: dapine -ms.date: 08/13/2024 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Options pattern in .NET diff --git a/docs/core/extensions/windows-service.md b/docs/core/extensions/windows-service.md index e117b5dbedcf5..bd535e757546c 100644 --- a/docs/core/extensions/windows-service.md +++ b/docs/core/extensions/windows-service.md @@ -3,8 +3,9 @@ title: Create Windows Service using BackgroundService description: Learn how to create a Windows Service using the BackgroundService in .NET. author: IEvangelist ms.author: dapine -ms.date: 03/25/2024 +ms.date: 10/22/2025 ms.topic: tutorial +ai-usage: ai-assisted --- # Create Windows Service using `BackgroundService` From efede64567333b912a2dafb453213a3e685c53bd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:36:31 +0000 Subject: [PATCH 11/30] Complete freshness pass for core/tools and core/testing articles Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/testing/unit-testing-code-coverage.md | 3 ++- docs/core/testing/unit-testing-csharp-with-mstest.md | 3 ++- docs/core/testing/unit-testing-csharp-with-nunit.md | 3 ++- docs/core/testing/unit-testing-csharp-with-xunit.md | 3 ++- docs/core/tools/global-json.md | 3 ++- docs/core/tools/global-tools.md | 3 ++- docs/core/tools/telemetry.md | 3 ++- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/core/testing/unit-testing-code-coverage.md b/docs/core/testing/unit-testing-code-coverage.md index 80e2e5ada44a4..5597346258ef7 100644 --- a/docs/core/testing/unit-testing-code-coverage.md +++ b/docs/core/testing/unit-testing-code-coverage.md @@ -3,7 +3,8 @@ title: Use code coverage for unit testing description: Learn how to use the code coverage capabilities for .NET unit tests. author: IEvangelist ms.author: dapine -ms.date: 11/11/2021 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Use code coverage for unit testing diff --git a/docs/core/testing/unit-testing-csharp-with-mstest.md b/docs/core/testing/unit-testing-csharp-with-mstest.md index 69376c64f1d28..f7cdaa0103d74 100644 --- a/docs/core/testing/unit-testing-csharp-with-mstest.md +++ b/docs/core/testing/unit-testing-csharp-with-mstest.md @@ -3,7 +3,8 @@ title: Unit testing C# with MSTest and .NET description: Learn unit test concepts in C# and .NET through an interactive experience building a sample solution step-by-step using dotnet test and MSTest. author: ncarandini ms.author: wiwagn -ms.date: 03/09/2022 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Unit testing C# with MSTest and .NET diff --git a/docs/core/testing/unit-testing-csharp-with-nunit.md b/docs/core/testing/unit-testing-csharp-with-nunit.md index 6c2e180417de0..2bde620198c5a 100644 --- a/docs/core/testing/unit-testing-csharp-with-nunit.md +++ b/docs/core/testing/unit-testing-csharp-with-nunit.md @@ -2,8 +2,9 @@ title: Unit testing C# with NUnit and .NET Core description: Learn unit test concepts in C# and .NET Core through an interactive experience building a sample solution step-by-step using dotnet test and NUnit. author: rprouse -ms.date: 03/27/2024 +ms.date: 10/22/2025 ms.custom: devdivchpfy22 +ai-usage: ai-assisted --- # Unit testing C# with NUnit and .NET Core diff --git a/docs/core/testing/unit-testing-csharp-with-xunit.md b/docs/core/testing/unit-testing-csharp-with-xunit.md index 2be26dd9d0082..c35fa91f899d3 100644 --- a/docs/core/testing/unit-testing-csharp-with-xunit.md +++ b/docs/core/testing/unit-testing-csharp-with-xunit.md @@ -3,7 +3,8 @@ title: Unit testing C# code in .NET using dotnet test and xUnit description: Learn unit test concepts in C# and .NET through an interactive experience building a sample solution step-by-step using dotnet test and xUnit. author: ardalis ms.author: wiwagn -ms.date: 03/07/2024 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Unit testing C# in .NET using dotnet test and xUnit diff --git a/docs/core/tools/global-json.md b/docs/core/tools/global-json.md index 116c9ddd9e627..a10f8da2f828f 100644 --- a/docs/core/tools/global-json.md +++ b/docs/core/tools/global-json.md @@ -2,8 +2,9 @@ title: global.json overview description: Learn how to use the global.json file to set the .NET SDK version when running .NET CLI commands. ms.topic: how-to -ms.date: 07/05/2024 +ms.date: 10/22/2025 ms.custom: "updateeachrelease" +ai-usage: ai-assisted --- # global.json overview diff --git a/docs/core/tools/global-tools.md b/docs/core/tools/global-tools.md index 1fdcfafa9989d..ba085ac04867c 100644 --- a/docs/core/tools/global-tools.md +++ b/docs/core/tools/global-tools.md @@ -3,8 +3,9 @@ title: .NET tools description: How to install, use, update, and remove .NET tools. Covers global tools, tool-path tools, and local tools. author: KathleenDollard ms.topic: how-to -ms.date: 07/25/2023 +ms.date: 10/22/2025 ms.custom: devdivchpfy22 +ai-usage: ai-assisted --- # How to manage .NET tools diff --git a/docs/core/tools/telemetry.md b/docs/core/tools/telemetry.md index 55b143f1a9397..04249a6b6de7b 100644 --- a/docs/core/tools/telemetry.md +++ b/docs/core/tools/telemetry.md @@ -2,7 +2,8 @@ title: .NET SDK and .NET CLI telemetry description: The .NET SDK and the .NET CLI collect usage information and send it to Microsoft. Learn what data is collected and how to opt out. author: KathleenDollard -ms.date: 10/07/2025 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # .NET SDK and .NET CLI telemetry From 161ecd3c80c81ca18d96a94ac7a92437460145de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:44:49 +0000 Subject: [PATCH 12/30] Complete freshness pass for all 45 existing articles (2 desktop articles not found in repo) Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/deploying/native-aot/index.md | 3 ++- docs/core/deploying/single-file/overview.md | 3 ++- docs/core/resilience/http-resilience.md | 3 ++- docs/core/versions/selection.md | 3 ++- docs/fundamentals/code-analysis/code-style-rule-options.md | 3 ++- .../task-based-asynchronous-pattern-tap.md | 3 ++- docs/standard/base-types/composite-formatting.md | 3 ++- docs/standard/base-types/formatting-types.md | 3 ++- docs/standard/exceptions/best-practices-for-exceptions.md | 3 ++- docs/standard/garbage-collection/fundamentals.md | 3 ++- docs/standard/garbage-collection/implementing-dispose.md | 3 ++- docs/standard/io/file-path-formats.md | 3 ++- .../parallel-programming/dataflow-task-parallel-library.md | 3 ++- .../task-based-asynchronous-programming.md | 3 ++- .../serialization/system-text-json/converters-how-to.md | 3 ++- 15 files changed, 30 insertions(+), 15 deletions(-) diff --git a/docs/core/deploying/native-aot/index.md b/docs/core/deploying/native-aot/index.md index 79c5b2c77edf0..a85a0623f4e7c 100644 --- a/docs/core/deploying/native-aot/index.md +++ b/docs/core/deploying/native-aot/index.md @@ -2,7 +2,8 @@ title: Native AOT deployment overview description: Learn what Native AOT deployments are and why you should consider using it as part of the publishing your app with .NET 7 and later. author: lakshanf -ms.date: 06/12/2023 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Native AOT deployment diff --git a/docs/core/deploying/single-file/overview.md b/docs/core/deploying/single-file/overview.md index 231548313ae64..ecab2579fcf90 100644 --- a/docs/core/deploying/single-file/overview.md +++ b/docs/core/deploying/single-file/overview.md @@ -2,8 +2,9 @@ title: Create a single file for application deployment description: Learn what single file application is and why you should consider using this application deployment model. author: lakshanf -ms.date: 06/21/2022 +ms.date: 10/22/2025 ms.custom: kr2b-contr-experiment +ai-usage: ai-assisted --- # Single-file deployment diff --git a/docs/core/resilience/http-resilience.md b/docs/core/resilience/http-resilience.md index da8c78bb57442..a63bc369a42ef 100644 --- a/docs/core/resilience/http-resilience.md +++ b/docs/core/resilience/http-resilience.md @@ -3,7 +3,8 @@ title: "Build resilient HTTP apps: Key development patterns" description: Learn how to build resilient HTTP apps using the Microsoft.Extensions.Http.Resilience NuGet package. author: IEvangelist ms.author: dapine -ms.date: 07/01/2024 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Build resilient HTTP apps: Key development patterns diff --git a/docs/core/versions/selection.md b/docs/core/versions/selection.md index 245c105ccf13b..349a5602c7ac4 100644 --- a/docs/core/versions/selection.md +++ b/docs/core/versions/selection.md @@ -3,7 +3,8 @@ title: Select which .NET version to use description: Learn how .NET automatically finds and chooses runtime versions for your program. Additionally, this article teaches you how to force a specific version. author: adegeo ms.author: adegeo -ms.date: 07/08/2021 +ms.date: 10/22/2025 +ai-usage: ai-assisted --- # Select the .NET version to use diff --git a/docs/fundamentals/code-analysis/code-style-rule-options.md b/docs/fundamentals/code-analysis/code-style-rule-options.md index 91c7eceb821d7..e806a9597431c 100644 --- a/docs/fundamentals/code-analysis/code-style-rule-options.md +++ b/docs/fundamentals/code-analysis/code-style-rule-options.md @@ -1,9 +1,10 @@ --- title: .NET code style rule options description: Learn how to specify .NET code style options. -ms.date: 04/26/2024 +ms.date: 10/22/2025 author: gewarren ms.author: gewarren +ai-usage: ai-assisted --- # Code-style rule options diff --git a/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md b/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md index e6bb5a3035d36..1ecff0c8b636b 100644 --- a/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md +++ b/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md @@ -1,7 +1,7 @@ --- title: "Task-based Asynchronous Pattern (TAP): Introduction and overview" description: "Learn about the Task-based Asynchronous Pattern (TAP), and compare it to the legacy patterns: Asynchronous Programming Model (APM) and Event-based Asynchronous Pattern (EAP)." -ms.date: 03/03/2022 +ms.date: 10/22/2025 dev_langs: - "csharp" - "vb" @@ -10,6 +10,7 @@ helpviewer_keywords: - "TAP, .NET support for" - "Task-based Asynchronous Pattern, .NET support for" - ".NET, asynchronous design patterns" +ai-usage: ai-assisted --- # Task-based asynchronous pattern (TAP) in .NET: Introduction and overview diff --git a/docs/standard/base-types/composite-formatting.md b/docs/standard/base-types/composite-formatting.md index 5e37ee4bba0b8..03af00d524b33 100644 --- a/docs/standard/base-types/composite-formatting.md +++ b/docs/standard/base-types/composite-formatting.md @@ -1,7 +1,7 @@ --- title: Composite formatting description: Learn about .NET composite formatting, which takes as input a list of objects and a composite format string, containing fixed text with indexed placeholders. -ms.date: 08/07/2023 +ms.date: 10/22/2025 ms.topic: concept-article dev_langs: - "csharp" @@ -13,6 +13,7 @@ helpviewer_keywords: - "strings [.NET], composite" - "composite formatting" - "objects [.NET], formatting multiple objects" +ai-usage: ai-assisted --- # Composite formatting diff --git a/docs/standard/base-types/formatting-types.md b/docs/standard/base-types/formatting-types.md index e83111a46a285..2388ef6006580 100644 --- a/docs/standard/base-types/formatting-types.md +++ b/docs/standard/base-types/formatting-types.md @@ -1,7 +1,7 @@ --- title: "Overview: How to format numbers, dates, enums, and other types in .NET" description: "Learn how to convert instances of .NET types to formatted strings. Override the ToString method, make formatting culture-sensitive, and use ICustomFormatter." -ms.date: 02/25/2022 +ms.date: 10/22/2025 dev_langs: - "csharp" - "vb" @@ -24,6 +24,7 @@ helpviewer_keywords: - "base types [.NET], formatting" - "custom formatting [.NET]" - "strings [.NET], formatting" +ai-usage: ai-assisted --- # Overview: How to format numbers, dates, enums, and other types in .NET diff --git a/docs/standard/exceptions/best-practices-for-exceptions.md b/docs/standard/exceptions/best-practices-for-exceptions.md index eab06b99a2329..d55d3cf6942ee 100644 --- a/docs/standard/exceptions/best-practices-for-exceptions.md +++ b/docs/standard/exceptions/best-practices-for-exceptions.md @@ -1,12 +1,13 @@ --- title: "Best practices for exceptions" description: Learn best practices for exceptions, such as using try/catch/finally, handling common conditions without exceptions, and using predefined .NET exception types. -ms.date: 04/30/2024 +ms.date: 10/22/2025 dev_langs: - "csharp" - "vb" helpviewer_keywords: - "exceptions, best practices" +ai-usage: ai-assisted --- # Best practices for exceptions diff --git a/docs/standard/garbage-collection/fundamentals.md b/docs/standard/garbage-collection/fundamentals.md index c7f4513ef9a0f..ef3da60bfaa8d 100644 --- a/docs/standard/garbage-collection/fundamentals.md +++ b/docs/standard/garbage-collection/fundamentals.md @@ -1,7 +1,7 @@ --- title: Fundamentals of garbage collection description: Learn how the garbage collector works and how it can be configured for optimum performance. -ms.date: 07/22/2022 +ms.date: 10/22/2025 ms.custom: devdivchpfy22 helpviewer_keywords: - "garbage collection, generations" @@ -11,6 +11,7 @@ helpviewer_keywords: - "garbage collection, workstation" - "garbage collection, managed heap" ms.assetid: 67c5a20d-1be1-4ea7-8a9a-92b0b08658d2 +ai-usage: ai-assisted --- # Fundamentals of garbage collection diff --git a/docs/standard/garbage-collection/implementing-dispose.md b/docs/standard/garbage-collection/implementing-dispose.md index d2fd4f5845170..c37936a38a765 100644 --- a/docs/standard/garbage-collection/implementing-dispose.md +++ b/docs/standard/garbage-collection/implementing-dispose.md @@ -1,7 +1,7 @@ --- title: "Implement a Dispose method" description: In this article, learn to implement the Dispose method, which releases unmanaged resources used by your code in .NET. -ms.date: 07/20/2023 +ms.date: 10/22/2025 dev_langs: - "csharp" - "vb" @@ -9,6 +9,7 @@ helpviewer_keywords: - "Dispose method" - "garbage collection, Dispose method" ms.topic: how-to +ai-usage: ai-assisted --- # Implement a Dispose method diff --git a/docs/standard/io/file-path-formats.md b/docs/standard/io/file-path-formats.md index d1b733e9b6903..53cd29f31e1a2 100644 --- a/docs/standard/io/file-path-formats.md +++ b/docs/standard/io/file-path-formats.md @@ -1,7 +1,7 @@ --- title: "File path formats on Windows systems" description: In this article, learn about file path formats on Windows systems, such as traditional DOS paths, DOS device paths, and universal naming convention (UNC) paths. -ms.date: "06/06/2019" +ms.date: "10/22/2025" dev_langs: - "csharp" - "vb" @@ -9,6 +9,7 @@ helpviewer_keywords: - "I/O, long paths" - "long paths" - "path formats, Windows" +ai-usage: ai-assisted --- # File path formats on Windows systems diff --git a/docs/standard/parallel-programming/dataflow-task-parallel-library.md b/docs/standard/parallel-programming/dataflow-task-parallel-library.md index 85e8a0ce2b87e..232d1c98f0b88 100644 --- a/docs/standard/parallel-programming/dataflow-task-parallel-library.md +++ b/docs/standard/parallel-programming/dataflow-task-parallel-library.md @@ -1,7 +1,7 @@ --- title: "Dataflow (Task Parallel Library)" description: Learn how to use dataflow components in the Task Parallel Library (TPL) to improve the robustness of concurrency-enabled applications. -ms.date: "03/30/2017" +ms.date: "10/22/2025" dev_langs: - "csharp" - "vb" @@ -9,6 +9,7 @@ helpviewer_keywords: - "Task Parallel Library, dataflows" - "TPL dataflow library" ms.assetid: 643575d0-d26d-4c35-8de7-a9c403e97dd6 +ai-usage: ai-assisted --- # Dataflow (Task Parallel Library) diff --git a/docs/standard/parallel-programming/task-based-asynchronous-programming.md b/docs/standard/parallel-programming/task-based-asynchronous-programming.md index e01a6fc89813c..ad55956b634ad 100644 --- a/docs/standard/parallel-programming/task-based-asynchronous-programming.md +++ b/docs/standard/parallel-programming/task-based-asynchronous-programming.md @@ -1,7 +1,7 @@ --- title: "Task-based asynchronous programming - .NET" description: In this article, learn about task-based asynchronous programming through the Task Parallel Library (TPL) in .NET. -ms.date: 06/03/2024 +ms.date: 10/22/2025 ms.custom: devdivchpfy22 dev_langs: - "csharp" @@ -9,6 +9,7 @@ dev_langs: helpviewer_keywords: - "parallelism, task" ms.assetid: 458b5e69-5210-45e5-bc44-3888f86abd6f +ai-usage: ai-assisted --- # Task-based asynchronous programming diff --git a/docs/standard/serialization/system-text-json/converters-how-to.md b/docs/standard/serialization/system-text-json/converters-how-to.md index 59bf9b818a5d3..7a788ed51bed0 100644 --- a/docs/standard/serialization/system-text-json/converters-how-to.md +++ b/docs/standard/serialization/system-text-json/converters-how-to.md @@ -1,7 +1,7 @@ --- title: "How to write custom converters for JSON serialization - .NET" description: "Learn how to create custom converters for the JSON serialization classes that are provided in the System.Text.Json namespace." -ms.date: 05/12/2022 +ms.date: 10/22/2025 no-loc: [System.Text.Json, Newtonsoft.Json] helpviewer_keywords: - "JSON serialization" @@ -10,6 +10,7 @@ helpviewer_keywords: - "objects, serializing" - "converters" ms.topic: how-to +ai-usage: ai-assisted --- # How to write custom converters for JSON serialization (marshalling) in .NET From a1ca5d5c41b8dfe0dc1af6e727918ae873b5602d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:09:39 +0000 Subject: [PATCH 13/30] Second editing pass: Apply more aggressive present tense and contraction transformations (batch 1) Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/extensions/dependency-injection.md | 2 +- docs/core/extensions/logging.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md index cb9701da5255f..b1f52ac1b1547 100644 --- a/docs/core/extensions/dependency-injection.md +++ b/docs/core/extensions/dependency-injection.md @@ -276,7 +276,7 @@ Every subsequent request of the service implementation from the dependency injec Register singleton services with . Singleton services must be thread safe and are often used in stateless services. -In apps that process requests, singleton services are disposed when the is disposed on application shutdown. Because memory is not released until the app is shut down, consider memory use with a singleton service. +In apps that process requests, singleton services are disposed when the is disposed on application shutdown. Because memory isn't released until the app shuts down, consider memory use with a singleton service. ## Service registration methods diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index 7254388cd73e2..ba1bd431b17a7 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -9,7 +9,7 @@ ai-usage: ai-assisted # Logging in C# and .NET -.NET supports high performance, structured logging via the API to help monitor application behavior and diagnose issues. Logs can be written to different destinations by configuring different [logging providers](logging-providers.md). Basic logging providers are built-in and there are many third-party providers available as well. +.NET supports high performance, structured logging via the API to help monitor application behavior and diagnose issues. Configure different [logging providers](logging-providers.md) to write logs to different destinations. Basic logging providers are built-in, and many third-party providers are available. ## Get started @@ -24,7 +24,7 @@ In the next section you see how to improve the code considering scale, performan The preceding example: -- Creates an . The `ILoggerFactory` stores all the configuration that determines where log messages are sent. In this case, you configure the console [logging provider](logging-providers.md) so that log messages are written to the console. +- Creates an . The `ILoggerFactory` stores all the configuration that determines where log messages are sent. In this case, configure the console [logging provider](logging-providers.md) so that log messages are written to the console. - Creates an with a category named "Program". The [category](#log-category) is a `string` that's associated with each message logged by the `ILogger` object. It groups log messages from the same class (or category) together when searching or filtering logs. - Calls to log a message at the `Information` level. The [log level](#log-level) indicates the severity of the logged event and filters out less important log messages. The log entry also includes a [message template](#log-message-template) `"Hello World! Logging is {Description}."` and a key-value pair `Description = fun`. The key name (or placeholder) comes from the word inside the curly braces in the template, and the value comes from the remaining method argument. @@ -324,7 +324,7 @@ The following table lists the value | [Debug](xref:Microsoft.Extensions.Logging.LogLevel) | 1 | | For debugging and development. Use with caution in production due to the high volume. | | [Information](xref:Microsoft.Extensions.Logging.LogLevel) | 2 | | Tracks the general flow of the app. May have long-term value. | | [Warning](xref:Microsoft.Extensions.Logging.LogLevel) | 3 | | For abnormal or unexpected events. Typically includes errors or conditions that don't cause the app to fail. | -| [Error](xref:Microsoft.Extensions.Logging.LogLevel) | 4 | | For errors and exceptions that cannot be handled. These messages indicate a failure in the current operation or request, not an app-wide failure. | +| [Error](xref:Microsoft.Extensions.Logging.LogLevel) | 4 | | For errors and exceptions that can't be handled. These messages indicate a failure in the current operation or request, not an app-wide failure. | | [Critical](xref:Microsoft.Extensions.Logging.LogLevel) | 5 | | For failures that require immediate attention. Examples: data loss scenarios, out of disk space. | | [None](xref:Microsoft.Extensions.Logging.LogLevel) | 6 | | Specifies that no messages should be written. | @@ -629,7 +629,7 @@ The preceding code relies on two NuGet packages: - [Microsoft.Extensions.Hosting](https://www.nuget.org/packages/Microsoft.Extensions.Hosting) - [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) -Its project file would look similar to the following: +Its project file looks similar to this: ```xml @@ -655,7 +655,7 @@ Logging should be so fast that it isn't worth the performance cost of asynchrono ## Change log levels in a running app -The Logging API doesn't include a scenario to change log levels while an app is running. However, some configuration providers can reload configuration, which takes immediate effect on logging configuration. For example, the [File Configuration Provider](configuration-providers.md#file-configuration-provider) reloads logging configuration by default. If the configuration is changed in code while an app is running, the app can call [IConfigurationRoot.Reload](xref:Microsoft.Extensions.Configuration.IConfigurationRoot.Reload%2A) to update the app's logging configuration. +The Logging API doesn't include a scenario to change log levels while an app is running. However, some configuration providers can reload configuration, which takes immediate effect on logging configuration. For example, the [File Configuration Provider](configuration-providers.md#file-configuration-provider) reloads logging configuration by default. If you change the configuration in code while an app is running, the app can call [IConfigurationRoot.Reload](xref:Microsoft.Extensions.Configuration.IConfigurationRoot.Reload%2A) to update the app's logging configuration. ## NuGet packages From 4ae376a8288dbe49f02fea1124ee875005bf42b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:12:05 +0000 Subject: [PATCH 14/30] Second editing pass: Apply systematic present tense and contraction transformations across all 45 articles Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/deploying/native-aot/index.md | 2 +- docs/core/deploying/single-file/overview.md | 8 ++++---- docs/core/extensions/caching.md | 4 ++-- docs/core/extensions/channels.md | 8 ++++---- .../dependency-injection-guidelines.md | 6 +++--- .../extensions/dependency-injection-usage.md | 2 +- .../extensions/logger-message-generator.md | 4 ++-- docs/core/extensions/logging-providers.md | 2 +- docs/core/extensions/options.md | 6 +++--- docs/core/extensions/windows-service.md | 10 +++++----- docs/core/resilience/http-resilience.md | 8 ++++---- .../testing/unit-testing-code-coverage.md | 12 +++++------ .../unit-testing-csharp-with-mstest.md | 2 +- .../testing/unit-testing-csharp-with-nunit.md | 2 +- .../testing/unit-testing-csharp-with-xunit.md | 8 ++++---- docs/core/versions/selection.md | 2 +- .../code-analysis/code-style-rule-options.md | 2 +- .../networking/http/httpclient-guidelines.md | 2 +- .../task-based-asynchronous-pattern-tap.md | 8 ++++---- .../base-types/composite-formatting.md | 2 +- docs/standard/base-types/formatting-types.md | 20 +++++++++---------- .../best-practices-for-exceptions.md | 6 +++--- .../garbage-collection/fundamentals.md | 6 +++--- .../implementing-dispose.md | 4 ++-- docs/standard/io/file-path-formats.md | 12 +++++------ .../dataflow-task-parallel-library.md | 18 ++++++++--------- .../task-based-asynchronous-programming.md | 4 ++-- .../system-text-json/converters-how-to.md | 14 ++++++------- 28 files changed, 92 insertions(+), 92 deletions(-) diff --git a/docs/core/deploying/native-aot/index.md b/docs/core/deploying/native-aot/index.md index a85a0623f4e7c..5f578e3fa7d0d 100644 --- a/docs/core/deploying/native-aot/index.md +++ b/docs/core/deploying/native-aot/index.md @@ -135,7 +135,7 @@ Native AOT apps have the following limitations: - Implies compilation into a single file, which has known [incompatibilities](../single-file/overview.md#api-incompatibility). - Apps include required runtime libraries (just like [self-contained apps](../index.md#self-contained-deployment), increasing their size as compared to framework-dependent apps). - always use their interpreted form, which is slower than run-time generated compiled code. -- Generic parameters substituted with struct type arguments will have specialized code generated for each instantiation. In the dynamic runtime, many instantiations are generated on-demand. In Native AOT, all instantiations are pre-generated. This can have significant impact to the disk size of the application. Generic virtual methods and generic instance methods will also have an instantiation for every implementing or overriding type. +- Generic parameters substituted with struct type arguments has specialized code generated for each instantiation. In the dynamic runtime, many instantiations are generated on-demand. In Native AOT, all instantiations are pre-generated. This can have significant impact to the disk size of the application. Generic virtual methods and generic instance methods will also have an instantiation for every implementing or overriding type. - Not all the runtime libraries are fully annotated to be Native AOT compatible. That is, some warnings in the runtime libraries aren't actionable by end developers. - [Diagnostic support for debugging and profiling](./diagnostics.md) with some limitations. - Support for some ASP.NET Core features. For more information, see [ASP.NET Core support for Native AOT](/aspnet/core/fundamentals/native-aot/). diff --git a/docs/core/deploying/single-file/overview.md b/docs/core/deploying/single-file/overview.md index ecab2579fcf90..2a432d4364386 100644 --- a/docs/core/deploying/single-file/overview.md +++ b/docs/core/deploying/single-file/overview.md @@ -210,11 +210,11 @@ We have some recommendations for fixing common scenarios: Some workflows require post-processing of binaries before bundling. A common example is signing. The dotnet SDK provides MSBuild extension points to allow processing binaries just before single-file bundling. The available APIs are: -- A target `PrepareForBundle` that will be called before `GenerateSingleFileBundle` -- An `` containing all files that will be bundled +- A target `PrepareForBundle` that is called before `GenerateSingleFileBundle` +- An `` containing all files that is bundled - A Property `AppHostFile` that will specify the apphost template. Post-processing might want to exclude the apphost from processing. -To plug into this involves creating a target that will be executed between `PrepareForBundle` and `GenerateSingleFileBundle`. +To plug into this involves creating a target that is executed between `PrepareForBundle` and `GenerateSingleFileBundle`. Consider the following .NET project `Target` node example: @@ -226,7 +226,7 @@ It's possible that tooling will need to copy files in the process of signing. Th ### Compress assemblies in single-file apps -Single-file apps can be created with compression enabled on the embedded assemblies. Set the `EnableCompressionInSingleFile` property to `true`. The single file that's produced will have all of the embedded assemblies compressed, which can significantly reduce the size of the executable. +Single-file apps can be created with compression enabled on the embedded assemblies. Set the `EnableCompressionInSingleFile` property to `true`. The single file that's produced has all of the embedded assemblies compressed, which can significantly reduce the size of the executable. Compression comes with a performance cost. On application start, the assemblies must be decompressed into memory, which takes some time. We recommend that you measure both the size change and startup cost of enabling compression before using it. The impact can vary significantly between different applications. diff --git a/docs/core/extensions/caching.md b/docs/core/extensions/caching.md index 6394a66daff06..bbaba0ef30415 100644 --- a/docs/core/extensions/caching.md +++ b/docs/core/extensions/caching.md @@ -96,7 +96,7 @@ Now that the cache is populated, another call to `IterateAlphabetAsync` is await :::code source="snippets/caching/memory-apis/Program.cs" range="56-66"::: -If the `cache` contains the `letter` key, and the `value` is an instance of an `AlphabetLetter` it's written to the console. When the `letter` key is not in the cache, it was evicted and its post eviction callback was invoked. +If the `cache` contains the `letter` key, and the `value` is an instance of an `AlphabetLetter` it's written to the console. When the `letter` key isn't in the cache, it was evicted and its post eviction callback was invoked. #### Additional extension methods @@ -262,7 +262,7 @@ Consider any of the available implementations of the `IDistributedCache` from th ### Distributed caching API -The distributed caching APIs are a bit more primitive than their in-memory caching API counterparts. The key-value pairs are a bit more basic. In-memory caching keys are based on an `object`, whereas the distributed keys are a `string`. With in-memory caching, the value can be any strongly-typed generic, whereas values in distributed caching are persisted as `byte[]`. That's not to say that various implementations don't expose strongly-typed generic values but that would be an implementation detail. +The distributed caching APIs are a bit more primitive than their in-memory caching API counterparts. The key-value pairs are a bit more basic. In-memory caching keys are based on an `object`, whereas the distributed keys are a `string`. With in-memory caching, the value can be any strongly-typed generic, whereas values in distributed caching are persisted as `byte[]`. That's not to say that various implementations don't expose strongly-typed generic values but that is an implementation detail. #### Create values diff --git a/docs/core/extensions/channels.md b/docs/core/extensions/channels.md index 21d09a4d211c5..7e72567291738 100644 --- a/docs/core/extensions/channels.md +++ b/docs/core/extensions/channels.md @@ -15,7 +15,7 @@ This library is available in the [System.Threading.Channels](https://www.nuget.o ## Producer/consumer conceptual programming model -Channels are an implementation of the producer/consumer conceptual programming model. In this programming model, producers asynchronously produce data, and consumers asynchronously consume that data. In other words, this model passes data from one party to another through a first-in first-out ("FIFO") queue. Try to think of channels as you would any other common generic collection type, such as a `List`. The primary difference is that this collection manages synchronization and provides various consumption models through factory creation options. These options control the behavior of the channels, such as how many elements they're allowed to store and what happens if that limit is reached, or whether the channel is accessed by multiple producers or multiple consumers concurrently. +Channels are an implementation of the producer/consumer conceptual programming model. In this programming model, producers asynchronously produce data, and consumers asynchronously consume that data. In other words, this model passes data from one party to another through a first-in first-out ("FIFO") queue. Think of channels as any other common generic collection type, such as a `List`. The primary difference is that this collection manages synchronization and provides various consumption models through factory creation options. These options control the behavior of the channels, such as how many elements they're allowed to store and what happens if that limit is reached, or whether the channel is accessed by multiple producers or multiple consumers concurrently. ## Bounding strategies @@ -24,7 +24,7 @@ Depending on how a `Channel` is created, its reader and writer behave differe To create a channel that specifies a maximum capacity, call . To create a channel that is used by any number of readers and writers concurrently, call . Each bounding strategy exposes various creator-defined options, either or respectively. > [!NOTE] -> Regardless of the bounding strategy, a channel will always throw a when it's used after it's been closed. +> Regardless of the bounding strategy, a channel always throws a when it's used after it's been closed. ### Unbounded channels @@ -141,7 +141,7 @@ An alternative producer might use the `WriteAsync` method: :::code language="csharp" source="snippets/channels/Program.Producer.cs" id="whilewrite"::: -Again, the `Channel.Writer` is used within a `while` loop. But this time, the method is called. The method will continue only after the coordinates have been written. When the `while` loop exits, a call to is made, which signals that no more data is written to the channel. +Again, the `Channel.Writer` is used within a `while` loop. But this time, the method is called. The method continues only after the coordinates have been written. When the `while` loop exits, a call to is made, which signals that no more data is written to the channel. Another producer pattern is to use the method, consider the following code: @@ -156,7 +156,7 @@ There are several common channel consumer patterns. When a channel is never endi :::code language="csharp" source="snippets/channels/Program.Consumer.cs" id="whiletrue"::: > [!NOTE] -> This code will throw an exception if the channel is closed. +> This code throws an exception if the channel is closed. An alternative consumer could avoid this concern by using a nested while loop, as shown in the following code: diff --git a/docs/core/extensions/dependency-injection-guidelines.md b/docs/core/extensions/dependency-injection-guidelines.md index 460862b1cb631..9a61a8bd044e1 100644 --- a/docs/core/extensions/dependency-injection-guidelines.md +++ b/docs/core/extensions/dependency-injection-guidelines.md @@ -159,8 +159,8 @@ The factory method of a singleton service, such as the second argument to [AddSi - **Coupling**: It can couple otherwise unrelated requests. - **Testing challenges**: Shared state and coupling can make unit testing more difficult. - **Memory impact**: A singleton may keep a large object graph alive in memory for the lifetime of the application. - - **Fault tolerance**: If a singleton or any part of its dependency tree fails, it cannot easily recover. - - **Configuration reloading**: Singletons generally cannot support "hot reload" of configuration values. + - **Fault tolerance**: If a singleton or any part of its dependency tree fails, it can't easily recover. + - **Configuration reloading**: Singletons generally can't support "hot reload" of configuration values. - **Scope leakage**: A singleton can inadvertently capture scoped or transient dependencies, effectively promoting them to singletons and causing unintended side effects. - **Initialization overhead**: When resolving a service, the IoC container needs to look up the singleton instance. If it doesn't already exist, it needs to create it in a thread-safe manner. In contrast, a stateless transient service is very cheap to create and destroy. @@ -181,7 +181,7 @@ When you register *Transient* services that implement , :::image type="content" source="media/transient-disposables-without-dispose.png" lightbox="media/transient-disposables-without-dispose.png" alt-text="Anti-pattern: Transient disposables without dispose. Do not copy!"::: -In the preceding anti-pattern, 1,000 `ExampleDisposable` objects are instantiated and rooted. They will not be disposed of until the `serviceProvider` instance is disposed. +In the preceding anti-pattern, 1,000 `ExampleDisposable` objects are instantiated and rooted. They won't be disposed of until the `serviceProvider` instance is disposed. For more information on debugging memory leaks, see [Debug a memory leak in .NET](../diagnostics/debug-memory-leak.md). diff --git a/docs/core/extensions/dependency-injection-usage.md b/docs/core/extensions/dependency-injection-usage.md index 6c1b23a1e9e32..2fc80b1099ec0 100644 --- a/docs/core/extensions/dependency-injection-usage.md +++ b/docs/core/extensions/dependency-injection-usage.md @@ -81,7 +81,7 @@ The example implementations all initialize their `Id` property with the result o :::code source="snippets/configuration/console-di/ExampleSingletonService.cs"::: -Each implementation is defined as `internal sealed` and implements its corresponding interface. They're not required to be `internal` or `sealed`, however, it's common to treat implementations as `internal` to avoid leaking implementation types to external consumers. Furthermore, since each type will not be extended, it's marked as `sealed`. For example, `ExampleSingletonService` implements `IExampleSingletonService`. +Each implementation is defined as `internal sealed` and implements its corresponding interface. They're not required to be `internal` or `sealed`, however, it's common to treat implementations as `internal` to avoid leaking implementation types to external consumers. Furthermore, since each type won't be extended, it's marked as `sealed`. For example, `ExampleSingletonService` implements `IExampleSingletonService`. ## Add a service that requires DI diff --git a/docs/core/extensions/logger-message-generator.md b/docs/core/extensions/logger-message-generator.md index 45e960ca4b479..3db052e66fc95 100644 --- a/docs/core/extensions/logger-message-generator.md +++ b/docs/core/extensions/logger-message-generator.md @@ -91,7 +91,7 @@ public static partial class Log } ``` -You can omit the logging message and will be provided for the message. The state will contain the arguments, formatted as key-value pairs. +You can omit the logging message and is provided for the message. The state will contain the arguments, formatted as key-value pairs. :::code source="snippets/logging/logger-message-generator/Program.cs"::: @@ -440,7 +440,7 @@ Additionally, there are benefits over manually using method is synchronous. - The lifetime of log state and objects should *not* be assumed. -An implementation of `ILoggerProvider` will create an `ILogger` via its method. If your implementation strives to queue logging messages in a non-blocking manner, the messages should first be materialized or the object state that's used to materialize a log entry should be serialized. Doing so avoids potential exceptions from disposed objects. +An implementation of `ILoggerProvider` creates an `ILogger` via its method. If your implementation strives to queue logging messages in a non-blocking manner, the messages should first be materialized or the object state that's used to materialize a log entry should be serialized. Doing so avoids potential exceptions from disposed objects. For more information, see [Implement a custom logging provider in .NET](custom-logging-provider.md). diff --git a/docs/core/extensions/options.md b/docs/core/extensions/options.md index b50ecee4ac147..e0138465e3310 100644 --- a/docs/core/extensions/options.md +++ b/docs/core/extensions/options.md @@ -92,7 +92,7 @@ In the preceding code, changes to the JSON configuration file after the app has : - Is useful in scenarios where options should be recomputed on every injection resolution, in [scoped or transient lifetimes](dependency-injection.md#service-lifetimes). For more information, see [Use IOptionsSnapshot to read updated data](#use-ioptionssnapshot-to-read-updated-data). -- Is registered as [Scoped](dependency-injection.md#scoped) and therefore cannot be injected into a Singleton service. +- Is registered as [Scoped](dependency-injection.md#scoped) and therefore can't be injected into a Singleton service. - Supports [named options](#named-options-support-using-iconfigurenamedoptions). : @@ -116,7 +116,7 @@ In the preceding code, changes to the JSON configuration file after the app has Using a generic wrapper type gives you the ability to decouple the lifetime of the option from the dependency injection (DI) container. The interface provides a layer of abstraction, including generic constraints, on your options type. This provides the following benefits: - The evaluation of the `T` configuration instance is deferred to the accessing of , rather than when it is injected. This is important because you can consume the `T` option from various places and choose the lifetime semantics without changing anything about `T`. -- When registering options of type `T`, you do not need to explicitly register the `T` type. This is a convenience when you're [authoring a library](options-library-authors.md) with simple defaults, and you don't want to force the caller to register options into the DI container with a specific lifetime. +- When registering options of type `T`, you don't need to explicitly register the `T` type. This is a convenience when you're [authoring a library](options-library-authors.md) with simple defaults, and you don't want to force the caller to register options into the DI container with a specific lifetime. - From the perspective of the API, it allows for constraints on the type `T` (in this case, `T` is constrained to a reference type). ## Use IOptionsSnapshot to read updated data @@ -169,7 +169,7 @@ The following example uses [!TIP] -> Some file systems, such as Docker containers and network shares, may not reliably send change notifications. When using the interface in these environments, set the `DOTNET_USE_POLLING_FILE_WATCHER` environment variable to `1` or `true` to poll the file system for changes. The interval at which changes are polled is every four seconds and is not configurable. +> Some file systems, such as Docker containers and network shares, may not reliably send change notifications. When using the interface in these environments, set the `DOTNET_USE_POLLING_FILE_WATCHER` environment variable to `1` or `true` to poll the file system for changes. The interval at which changes are polled is every four seconds and isn't configurable. > > For more information on Docker containers, see [Containerize a .NET app](../docker/build-container.md). diff --git a/docs/core/extensions/windows-service.md b/docs/core/extensions/windows-service.md index bd535e757546c..af94933b6a908 100644 --- a/docs/core/extensions/windows-service.md +++ b/docs/core/extensions/windows-service.md @@ -157,7 +157,7 @@ dotnet publish --output "C:\custom\publish\directory" For more information, see [`dotnet publish`](../tools/dotnet-publish.md). > [!IMPORTANT] -> With .NET 6, if you attempt to debug the app with the `true` setting, you will not be able to debug the app. For more information, see [Unable to attach to CoreCLR when debugging a 'PublishSingleFile' .NET 6 app](https://developercommunity.visualstudio.com/t/unable-to-attach-to-coreclr-when-debugging-a-publi/1523427). +> With .NET 6, if you attempt to debug the app with the `true` setting, you won't be able to debug the app. For more information, see [Unable to attach to CoreCLR when debugging a 'PublishSingleFile' .NET 6 app](https://developercommunity.visualstudio.com/t/unable-to-attach-to-coreclr-when-debugging-a-publi/1523427). ## Create the Windows Service @@ -238,9 +238,9 @@ With .NET 6, [new hosting exception-handling behaviors](../compatibility/core-li | Option | Description | |--|--| | | Ignore exceptions thrown in `BackgroundService`. | -| | The `IHost` will be stopped when an unhandled exception is thrown. | +| | The `IHost` is stopped when an unhandled exception is thrown. | -The default behavior before .NET 6 is `Ignore`, which resulted in *zombie processes* (a running process that didn't do anything). With .NET 6, the default behavior is `StopHost`, which results in the host being stopped when an exception is thrown. But it stops cleanly, meaning that the Windows Service management system will not restart the service. To correctly allow the service to be restarted, you can call with a non-zero exit code. Consider the following highlighted `catch` block: +The default behavior before .NET 6 is `Ignore`, which resulted in *zombie processes* (a running process that didn't do anything). With .NET 6, the default behavior is `StopHost`, which results in the host being stopped when an exception is thrown. But it stops cleanly, meaning that the Windows Service management system won't restart the service. To correctly allow the service to be restarted, you can call with a non-zero exit code. Consider the following highlighted `catch` block: :::code source="snippets/workers/windows-service/WindowsBackgroundService.cs" highlight="24-37"::: @@ -249,7 +249,7 @@ The default behavior before .NET 6 is `Ignore`, which resulted in *zombie proces To see the app created as a Windows Service, open **Services**. Select the Windows key (or Ctrl + Esc), and search from "Services". From the **Services** app, you should be able to find your service by its name. > [!IMPORTANT] -> By default, regular (non-admin) users cannot manage Windows services. To verify that this app functions as expected, you'll need to use an Admin account. +> By default, regular (non-admin) users can't manage Windows services. To verify that this app functions as expected, you'll need to use an Admin account. :::image type="content" source="media/windows-service.png" lightbox="media/windows-service.png" alt-text="The Services user interface."::: @@ -325,7 +325,7 @@ The service **Status** will transition from `STOP_PENDING` to **Stopped**. To delete the Windows Service, use the native Windows Service Control Manager's (sc.exe) delete command. Run PowerShell as an Administrator. > [!IMPORTANT] -> If the service is not in the **Stopped** state, it will not be immediately deleted. Ensure that the service is stopped before issuing the delete command. +> If the service isn't in the **Stopped** state, it won't be immediately deleted. Ensure that the service is stopped before issuing the delete command. ```powershell sc.exe delete ".NET Joke Service" diff --git a/docs/core/resilience/http-resilience.md b/docs/core/resilience/http-resilience.md index a63bc369a42ef..2bc135a314161 100644 --- a/docs/core/resilience/http-resilience.md +++ b/docs/core/resilience/http-resilience.md @@ -125,7 +125,7 @@ By default, the standard resilience handler is configured to make retries for al :::code language="csharp" source="snippets/http-resilience/Program.RetryOptions.cs" id="disable_for"::: -Alternatively, you can use the method, which disables retries for `POST`, `PATCH`, `PUT`, `DELETE`, and `CONNECT` requests. According to [RFC](https://www.rfc-editor.org/rfc/rfc7231#section-4.2.1), these methods are considered unsafe; meaning their semantics are not read-only: +Alternatively, you can use the method, which disables retries for `POST`, `PATCH`, `PUT`, `DELETE`, and `CONNECT` requests. According to [RFC](https://www.rfc-editor.org/rfc/rfc7231#section-4.2.1), these methods are considered unsafe; meaning their semantics aren't read-only: :::code language="csharp" source="snippets/http-resilience/Program.RetryOptions.cs" id="disable_for_unsafe_http_methods"::: @@ -282,7 +282,7 @@ services The preceding code results in the following exception: ```Output -System.InvalidOperationException: The ConfigureHttpClient method is not supported when creating gRPC clients. Unable to create client with name 'GreeterClient'. +System.InvalidOperationException: The ConfigureHttpClient method isn't supported when creating gRPC clients. Unable to create client with name 'GreeterClient'. ``` To resolve this issue, we recommend upgrading to `Grpc.Net.ClientFactory` version `2.64.0` or later. @@ -307,10 +307,10 @@ services.AddHttpClient().AddStandardResilienceHandler(); services.AddApplicationInsightsTelemetry(); ``` -The issue can be fixed by updating .NET Application Insights to version **2.23.0** or higher. If you cannot update it, then registering Application Insights services before resilience functionality, as shown below, will fix the issue: +The issue can be fixed by updating .NET Application Insights to version **2.23.0** or higher. If you can't update it, then registering Application Insights services before resilience functionality, as shown below, will fix the issue: ```csharp -// We register Application Insights first, and now it will be working correctly. +// We register Application Insights first, and now it is working correctly. services.AddApplicationInsightsTelemetry(); services.AddHttpClient().AddStandardResilienceHandler(); ``` diff --git a/docs/core/testing/unit-testing-code-coverage.md b/docs/core/testing/unit-testing-code-coverage.md index 5597346258ef7..824bc1281bd84 100644 --- a/docs/core/testing/unit-testing-code-coverage.md +++ b/docs/core/testing/unit-testing-code-coverage.md @@ -22,7 +22,7 @@ This article is based on the [sample source code project](/samples/dotnet/sample ## System under test -The "system under test" refers to the code that you're writing unit tests against, this could be an object, service, or anything else that exposes testable functionality. For this article, you'll create a class library that will be the system under test, and two corresponding unit test projects. +The "system under test" refers to the code that you're writing unit tests against, this could be an object, service, or anything else that exposes testable functionality. For this article, you'll create a class library that is the system under test, and two corresponding unit test projects. ### Create a class library @@ -109,7 +109,7 @@ namespace XUnit.Coverlet [Theory] [InlineData(-1), InlineData(0), InlineData(1)] public void IsPrime_ValuesLessThan2_ReturnFalse(int value) => - Assert.False(_primeService.IsPrime(value), $"{value} should not be prime"); + Assert.False(_primeService.IsPrime(value), $"{value} shouldn't be prime"); [Theory] [InlineData(2), InlineData(3), InlineData(5), InlineData(7)] @@ -119,7 +119,7 @@ namespace XUnit.Coverlet [Theory] [InlineData(4), InlineData(6), InlineData(8), InlineData(9)] public void IsPrime_NonPrimesLessThan10_ReturnFalse(int value) => - Assert.False(_primeService.IsPrime(value), $"{value} should not be prime"); + Assert.False(_primeService.IsPrime(value), $"{value} shouldn't be prime"); } } ``` @@ -132,7 +132,7 @@ From the command prompt, create a new solution to encapsulate the class library dotnet new sln -n XUnit.Coverage ``` -This will create a new solution file name `XUnit.Coverage` in the *UnitTestingCodeCoverage* directory. Add the projects to the root of the solution. +This creates a new solution file name `XUnit.Coverage` in the *UnitTestingCodeCoverage* directory. Add the projects to the root of the solution. ## [Linux](#tab/linux) @@ -165,7 +165,7 @@ There are two types of code coverage tools: In this section, the focus is on data collector tools. -.NET includes a built-in code coverage data collector, which is also available in Visual Studio. This data collector generates a binary *.coverage* file that can be used to generate reports in Visual Studio. The binary file is not human-readable, and it must be converted to a human-readable format before it can be used to generate reports outside of Visual Studio. +.NET includes a built-in code coverage data collector, which is also available in Visual Studio. This data collector generates a binary *.coverage* file that can be used to generate reports in Visual Studio. The binary file isn't human-readable, and it must be converted to a human-readable format before it can be used to generate reports outside of Visual Studio. > [!TIP] > The `dotnet-coverage` tool is a cross-platform tool that can be used to convert the binary coverage test results file to a human-readable format. For more information, see [dotnet-coverage](../additional-tools/dotnet-coverage.md). @@ -184,7 +184,7 @@ cd XUnit.Coverlet.Collector && dotnet test --collect:"XPlat Code Coverage" > [!NOTE] > The `"XPlat Code Coverage"` argument is a friendly name that corresponds to the data collectors from Coverlet. This name is required but is case insensitive. To use .NET's built-in Code Coverage data collector, use `"Code Coverage"`. -As part of the `dotnet test` run, a resulting *coverage.cobertura.xml* file is output to the *TestResults* directory. The XML file contains the results. This is a cross-platform option that relies on the .NET CLI, and it is great for build systems where MSBuild is not available. +As part of the `dotnet test` run, a resulting *coverage.cobertura.xml* file is output to the *TestResults* directory. The XML file contains the results. This is a cross-platform option that relies on the .NET CLI, and it is great for build systems where MSBuild isn't available. Below is the example *coverage.cobertura.xml* file. diff --git a/docs/core/testing/unit-testing-csharp-with-mstest.md b/docs/core/testing/unit-testing-csharp-with-mstest.md index f7cdaa0103d74..47a36ae387e66 100644 --- a/docs/core/testing/unit-testing-csharp-with-mstest.md +++ b/docs/core/testing/unit-testing-csharp-with-mstest.md @@ -125,7 +125,7 @@ namespace Prime.UnitTests.Services { bool result = _primeService.IsPrime(1); - Assert.IsFalse(result, "1 should not be prime"); + Assert.IsFalse(result, "1 shouldn't be prime"); } } } diff --git a/docs/core/testing/unit-testing-csharp-with-nunit.md b/docs/core/testing/unit-testing-csharp-with-nunit.md index 2bde620198c5a..e806a0d933e3b 100644 --- a/docs/core/testing/unit-testing-csharp-with-nunit.md +++ b/docs/core/testing/unit-testing-csharp-with-nunit.md @@ -143,7 +143,7 @@ namespace Prime.UnitTests.Services { var result = _primeService.IsPrime(1); - Assert.That(result, Is.False, "1 should not be prime"); + Assert.That(result, Is.False, "1 shouldn't be prime"); } } } diff --git a/docs/core/testing/unit-testing-csharp-with-xunit.md b/docs/core/testing/unit-testing-csharp-with-xunit.md index c35fa91f899d3..7b7b2334b6d4b 100644 --- a/docs/core/testing/unit-testing-csharp-with-xunit.md +++ b/docs/core/testing/unit-testing-csharp-with-xunit.md @@ -139,7 +139,7 @@ Update the *PrimeService.Tests* project: var primeService = new PrimeService(); bool result = primeService.IsPrime(1); - Assert.False(result, "1 should not be prime"); + Assert.False(result, "1 shouldn't be prime"); } } } @@ -170,7 +170,7 @@ Add prime number tests for 0 and -1. You *could* copy the test created in the pr var primeService = new PrimeService(); bool result = primeService.IsPrime(1); -Assert.False(result, "1 should not be prime"); +Assert.False(result, "1 shouldn't be prime"); ``` Copying test code when only a parameter changes results in code duplication and test bloat. The following xUnit attributes enable writing a suite of similar tests: @@ -187,7 +187,7 @@ public void IsPrime_InputIs1_ReturnFalse() var primeService = new PrimeService(); bool result = primeService.IsPrime(1); - Assert.False(result, "1 should not be prime"); + Assert.False(result, "1 shouldn't be prime"); } ``` @@ -216,7 +216,7 @@ public bool IsPrime(int candidate) Following the TDD approach, add more failing tests, then update the target code. See the [finished version of the tests](https://github.com/dotnet/samples/blob/main/core/getting-started/unit-testing-using-dotnet-test/PrimeService.Tests/PrimeService_IsPrimeShould.cs) and the [complete implementation of the library](https://github.com/dotnet/samples/blob/main/core/getting-started/unit-testing-using-dotnet-test/PrimeService/PrimeService.cs). -The completed `IsPrime` method is not an efficient algorithm for testing primality. +The completed `IsPrime` method isn't an efficient algorithm for testing primality. ### Additional resources diff --git a/docs/core/versions/selection.md b/docs/core/versions/selection.md index 349a5602c7ac4..454e817865070 100644 --- a/docs/core/versions/selection.md +++ b/docs/core/versions/selection.md @@ -98,7 +98,7 @@ A few usage examples demonstrate the behavior, if you target 5.0: Minor version roll-forward has one side-effect that may affect end users. Consider the following scenario: 01. The application specifies that 5.0 is required. -02. When run, version 5.0.* isn't installed, however, 5.1.0 is. Version 5.1.0 will be used. +02. When run, version 5.0.* isn't installed, however, 5.1.0 is. Version 5.1.0 is used. 03. Later, the user installs 5.0.3 and runs the application again, 5.0.3 will now be used. It's possible that 5.0.3 and 5.1.0 behave differently, particularly for scenarios like serializing binary data. diff --git a/docs/fundamentals/code-analysis/code-style-rule-options.md b/docs/fundamentals/code-analysis/code-style-rule-options.md index e806a9597431c..36ba85bb3865b 100644 --- a/docs/fundamentals/code-analysis/code-style-rule-options.md +++ b/docs/fundamentals/code-analysis/code-style-rule-options.md @@ -13,7 +13,7 @@ You can define and maintain consistent *code style* in your codebase by defining > [!TIP] > > - When you define code style options in an EditorConfig file, you're configuring how you want the [code style analyzers](overview.md#code-style-analysis) to analyze your code. The EditorConfig file is the configuration file for these analyzers. -> - Code style options can also be set in Visual Studio in the [Text editor options](/visualstudio/ide/code-styles-and-code-cleanup) dialog. These are per-user options that are only respected while editing in Visual Studio. These options are not respected at build time or by other IDEs. Additionally, if the project or solution opened inside Visual Studio has an EditorConfig file, then options from the EditorConfig file take precedence. In Visual Studio on Windows, you can also generate an EditorConfig file from your text-editor options. Select **Tools** > **Options** > **Text Editor** > [**C#** or **Basic**] > **Code Style** > **General**, and then click **Generate .editorconfig file from settings**. For more information, see [Code style preferences](/visualstudio/ide/code-styles-and-code-cleanup). +> - Code style options can also be set in Visual Studio in the [Text editor options](/visualstudio/ide/code-styles-and-code-cleanup) dialog. These are per-user options that are only respected while editing in Visual Studio. These options aren't respected at build time or by other IDEs. Additionally, if the project or solution opened inside Visual Studio has an EditorConfig file, then options from the EditorConfig file take precedence. In Visual Studio on Windows, you can also generate an EditorConfig file from your text-editor options. Select **Tools** > **Options** > **Text Editor** > [**C#** or **Basic**] > **Code Style** > **General**, and then click **Generate .editorconfig file from settings**. For more information, see [Code style preferences](/visualstudio/ide/code-styles-and-code-cleanup). Code style rules are divided into following subcategories: diff --git a/docs/fundamentals/networking/http/httpclient-guidelines.md b/docs/fundamentals/networking/http/httpclient-guidelines.md index aaeda8a37310e..756f248b49ded 100644 --- a/docs/fundamentals/networking/http/httpclient-guidelines.md +++ b/docs/fundamentals/networking/http/httpclient-guidelines.md @@ -29,7 +29,7 @@ The 15-minute interval was chosen arbitrarily for illustration purposes. You sho ## Pooled connections -The connection pool for an is linked to the underlying . When the instance is disposed, it disposes all existing connections inside the pool. If you later send a request to the same server, a new connection must be recreated. As a result, there's a performance penalty for unnecessary connection creation. Moreover, TCP ports are not released immediately after connection closure. (For more information on that, see TCP `TIME-WAIT` in [RFC 9293](https://www.rfc-editor.org/rfc/rfc9293.html#section-3.3.2).) If the rate of requests is high, the operating system limit of available ports might be exhausted. To avoid port exhaustion problems, we [recommend](#recommended-use) reusing instances for as many HTTP requests as possible. +The connection pool for an is linked to the underlying . When the instance is disposed, it disposes all existing connections inside the pool. If you later send a request to the same server, a new connection must be recreated. As a result, there's a performance penalty for unnecessary connection creation. Moreover, TCP ports aren't released immediately after connection closure. (For more information on that, see TCP `TIME-WAIT` in [RFC 9293](https://www.rfc-editor.org/rfc/rfc9293.html#section-3.3.2).) If the rate of requests is high, the operating system limit of available ports might be exhausted. To avoid port exhaustion problems, we [recommend](#recommended-use) reusing instances for as many HTTP requests as possible. ## Recommended use diff --git a/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md b/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md index 1ecff0c8b636b..8fe91845345d7 100644 --- a/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md +++ b/docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md @@ -18,11 +18,11 @@ In .NET, The task-based asynchronous pattern is the recommended asynchronous des ## Naming, parameters, and return types -TAP uses a single method to represent the initiation and completion of an asynchronous operation. This contrasts with both the Asynchronous Programming Model (APM or `IAsyncResult`) pattern and the Event-based Asynchronous Pattern (EAP). APM requires `Begin` and `End` methods. EAP requires a method that has the `Async` suffix and also requires one or more events, event handler delegate types, and `EventArg`-derived types. Asynchronous methods in TAP include the `Async` suffix after the operation name for methods that return awaitable types, such as , , , and . For example, an asynchronous `Get` operation that returns a `Task` can be named `GetAsync`. If you're adding a TAP method to a class that already contains an EAP method name with the `Async` suffix, use the suffix `TaskAsync` instead. For example, if the class already has a `GetAsync` method, use the name `GetTaskAsync`. If a method starts an asynchronous operation but does not return an awaitable type, its name should start with `Begin`, `Start`, or some other verb to suggest that this method does not return or throw the result of the operation.   +TAP uses a single method to represent the initiation and completion of an asynchronous operation. This contrasts with both the Asynchronous Programming Model (APM or `IAsyncResult`) pattern and the Event-based Asynchronous Pattern (EAP). APM requires `Begin` and `End` methods. EAP requires a method that has the `Async` suffix and also requires one or more events, event handler delegate types, and `EventArg`-derived types. Asynchronous methods in TAP include the `Async` suffix after the operation name for methods that return awaitable types, such as , , , and . For example, an asynchronous `Get` operation that returns a `Task` can be named `GetAsync`. If you're adding a TAP method to a class that already contains an EAP method name with the `Async` suffix, use the suffix `TaskAsync` instead. For example, if the class already has a `GetAsync` method, use the name `GetTaskAsync`. If a method starts an asynchronous operation but doesn't return an awaitable type, its name should start with `Begin`, `Start`, or some other verb to suggest that this method doesn't return or throw the result of the operation.   A TAP method returns either a or a , based on whether the corresponding synchronous method returns void or a type `TResult`. - The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. However, `out` and `ref` parameters are exempt from this rule and should be avoided entirely. Any data that would have been returned through an `out` or `ref` parameter should instead be returned as part of the `TResult` returned by , and should use a tuple or a custom data structure to accommodate multiple values. Also, consider adding a parameter even if the TAP method's synchronous counterpart does not offer one. + The parameters of a TAP method should match the parameters of its synchronous counterpart and should be provided in the same order. However, `out` and `ref` parameters are exempt from this rule and should be avoided entirely. Any data that has been returned through an `out` or `ref` parameter should instead be returned as part of the `TResult` returned by , and should use a tuple or a custom data structure to accommodate multiple values. Also, consider adding a parameter even if the TAP method's synchronous counterpart doesn't offer one. Methods that are devoted exclusively to the creation, manipulation, or combination of tasks (where the asynchronous intent of the method is clear in the method name or in the name of the type to which the method belongs) need not follow this naming pattern; such methods are often referred to as *combinators*. Examples of combinators include and , and are discussed in the [Using the Built-in Task-based Combinators](consuming-the-task-based-asynchronous-pattern.md#combinators) section of the article [Consuming the Task-based Asynchronous Pattern](consuming-the-task-based-asynchronous-pattern.md). @@ -52,7 +52,7 @@ TAP uses a single method to represent the initiation and completion of an asynch The class provides a life cycle for asynchronous operations, and that cycle is represented by the enumeration. To support corner cases of types that derive from and , and to support the separation of construction from scheduling, the class exposes a method. Tasks that are created by the public constructors are referred to as *cold tasks*, because they begin their life cycle in the non-scheduled state and are scheduled only when is called on these instances. - All other tasks begin their life cycle in a hot state, which means that the asynchronous operations they represent have already been initiated and their task status is an enumeration value other than . All tasks that are returned from TAP methods must be activated. **If a TAP method internally uses a task's constructor to instantiate the task to be returned, the TAP method must call on the object before returning it.** Consumers of a TAP method may safely assume that the returned task is active and should not try to call on any that is returned from a TAP method. Calling on an active task results in an exception. + All other tasks begin their life cycle in a hot state, which means that the asynchronous operations they represent have already been initiated and their task status is an enumeration value other than . All tasks that are returned from TAP methods must be activated. **If a TAP method internally uses a task's constructor to instantiate the task to be returned, the TAP method must call on the object before returning it.** Consumers of a TAP method may safely assume that the returned task is active and shouldn't try to call on any that is returned from a TAP method. Calling on an active task results in an exception. ## Cancellation (optional) @@ -65,7 +65,7 @@ TAP uses a single method to represent the initiation and completion of an asynch If a cancellation token has requested cancellation before the TAP method that accepts that token is called, the TAP method should return a task. However, if cancellation is requested while the asynchronous operation is running, the asynchronous operation need not accept the cancellation request. The returned task should end in the state only if the operation ends as a result of the cancellation request. If cancellation is requested but a result or an exception is still produced, the task should end in the or state. - For asynchronous methods that want to expose the ability to be canceled first and foremost, you don't have to provide an overload that doesn't accept a cancellation token. For methods that cannot be canceled, do not provide overloads that accept a cancellation token; this helps indicate to the caller whether the target method is actually cancelable. Consumer code that does not desire cancellation may call a method that accepts a and provide as the argument value. is functionally equivalent to the default . + For asynchronous methods that want to expose the ability to be canceled first and foremost, you don't have to provide an overload that doesn't accept a cancellation token. For methods that can't be canceled, don't provide overloads that accept a cancellation token; this helps indicate to the caller whether the target method is actually cancelable. Consumer code that doesn't desire cancellation may call a method that accepts a and provide as the argument value. is functionally equivalent to the default . ## Progress reporting (optional) diff --git a/docs/standard/base-types/composite-formatting.md b/docs/standard/base-types/composite-formatting.md index 03af00d524b33..fe4e17017ab7b 100644 --- a/docs/standard/base-types/composite-formatting.md +++ b/docs/standard/base-types/composite-formatting.md @@ -125,7 +125,7 @@ The way escaped braces are interpreted can lead to unexpected results. For examp 1. The first two opening braces (`{{`) are escaped and yield one opening brace. 1. The next three characters (`{0:`) are interpreted as the start of a format item. -1. The next character (`D`) would be interpreted as the Decimal standard numeric format specifier, but the next two escaped braces (`}}`) yield a single brace. Because the resulting string (`D}`) isn't a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string `D}`. +1. The next character (`D`) is interpreted as the Decimal standard numeric format specifier, but the next two escaped braces (`}}`) yield a single brace. Because the resulting string (`D}`) isn't a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string `D}`. 1. The last brace (`}`) is interpreted as the end of the format item. 1. The final result that's displayed is the literal string, `{D}`. The numeric value that was to be formatted isn't displayed. diff --git a/docs/standard/base-types/formatting-types.md b/docs/standard/base-types/formatting-types.md index 2388ef6006580..29c7f40b64b74 100644 --- a/docs/standard/base-types/formatting-types.md +++ b/docs/standard/base-types/formatting-types.md @@ -63,13 +63,13 @@ The following sections examine these methods for converting an object to its str ## Default formatting using the ToString method -Every type that is derived from automatically inherits a parameterless `ToString` method, which returns the name of the type by default. The following example illustrates the default `ToString` method. It defines a class named `Automobile` that has no implementation. When the class is instantiated and its `ToString` method is called, it displays its type name. Note that the `ToString` method is not explicitly called in the example. The method implicitly calls the `ToString` method of the object passed to it as an argument. +Every type that is derived from automatically inherits a parameterless `ToString` method, which returns the name of the type by default. The following example illustrates the default `ToString` method. It defines a class named `Automobile` that has no implementation. When the class is instantiated and its `ToString` method is called, it displays its type name. Note that the `ToString` method isn't explicitly called in the example. The method implicitly calls the `ToString` method of the object passed to it as an argument. [!code-csharp[Conceptual.Formatting.Overview#1](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/default1.cs#1)] [!code-vb[Conceptual.Formatting.Overview#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/default1.vb#1)] > [!WARNING] -> Starting with Windows 8.1, the Windows Runtime includes an interface with a single method, [IStringable.ToString](xref:Windows.Foundation.IStringable.ToString%2A), which provides default formatting support. However, we recommend that managed types do not implement the `IStringable` interface. For more information, see [The Windows Runtime and the IStringable Interface](../../fundamentals/runtime-libraries/system-object-tostring.md#the-windows-runtime-and-the-istringable-interface). +> Starting with Windows 8.1, the Windows Runtime includes an interface with a single method, [IStringable.ToString](xref:Windows.Foundation.IStringable.ToString%2A), which provides default formatting support. However, we recommend that managed types don't implement the `IStringable` interface. For more information, see [The Windows Runtime and the IStringable Interface](../../fundamentals/runtime-libraries/system-object-tostring.md#the-windows-runtime-and-the-istringable-interface). Because all types other than interfaces are derived from , this functionality is automatically provided to your custom classes or structures. However, the functionality offered by the default `ToString` method, is limited: Although it identifies the type, it fails to provide any information about an instance of the type. To provide a string representation of an object that provides information about that object, you must override the `ToString` method. @@ -78,7 +78,7 @@ Because all types other than interfaces are derived from , t ## Override the ToString method -Displaying the name of a type is often of limited use and does not allow consumers of your types to differentiate one instance from another. However, you can override the `ToString` method to provide a more useful representation of an object's value. The following example defines a `Temperature` object and overrides its `ToString` method to display the temperature in degrees Celsius. +Displaying the name of a type is often of limited use and doesn't allow consumers of your types to differentiate one instance from another. However, you can override the `ToString` method to provide a more useful representation of an object's value. The following example defines a `Temperature` object and overrides its `ToString` method to display the temperature in degrees Celsius. [!code-csharp[Conceptual.Formatting.Overview#2](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/overrides1.cs#2)] [!code-vb[Conceptual.Formatting.Overview#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/overrides1.vb#2)] @@ -112,7 +112,7 @@ All numeric types, date and time types, and enumeration types in .NET support a ### Standard format strings -A standard format string contains a single format specifier, which is an alphabetic character that defines the string representation of the object to which it is applied, along with an optional precision specifier that affects how many digits are displayed in the result string. If the precision specifier is omitted or is not supported, a standard format specifier is equivalent to a standard format string. +A standard format string contains a single format specifier, which is an alphabetic character that defines the string representation of the object to which it is applied, along with an optional precision specifier that affects how many digits are displayed in the result string. If the precision specifier is omitted or isn't supported, a standard format specifier is equivalent to a standard format string. .NET defines a set of standard format specifiers for all numeric types, all date and time types, and all enumeration types. For example, each of these categories supports a "G" standard format specifier, which defines a general string representation of a value of that type. @@ -143,7 +143,7 @@ Standard format strings for numeric types usually define a result string whose p - The property, which defines the number of digits in each group to the left of the decimal. -- The property, which determines the negative sign used in the result string if parentheses are not used to indicate negative values. +- The property, which determines the negative sign used in the result string if parentheses aren't used to indicate negative values. In addition, numeric format strings may include a precision specifier. The meaning of this specifier depends on the format string with which it is used, but it typically indicates either the total number of digits or the number of fractional digits that should appear in the result string. For example, the following example uses the "X4" standard numeric string and a precision specifier to create a string value that has four hexadecimal digits. @@ -227,7 +227,7 @@ A number of formatting or string conversion methods include a parameter of type ||| > [!NOTE] -> The `ToString` methods of the numeric types and date and time types are overloaded, and only some of the overloads include an parameter. If a method does not have a parameter of type , the object that is returned by the property is passed instead. For example, a call to the default method ultimately results in a method call such as the following: `Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture)`. +> The `ToString` methods of the numeric types and date and time types are overloaded, and only some of the overloads include an parameter. If a method doesn't have a parameter of type , the object that is returned by the property is passed instead. For example, a call to the default method ultimately results in a method call such as the following: `Int32.ToString("G", System.Globalization.CultureInfo.CurrentCulture)`. .NET provides three classes that implement : @@ -241,7 +241,7 @@ You can also implement your own format provider to replace any one of these clas ### Culture-sensitive formatting of numeric values -By default, the formatting of numeric values is culture-sensitive. If you do not specify a culture when you call a formatting method, the formatting conventions of the current culture are used. This is illustrated in the following example, which changes the current culture four times and then calls the method. In each case, the result string reflects the formatting conventions of the current culture. This is because the `ToString` and `ToString(String)` methods wrap calls to each numeric type's `ToString(String, IFormatProvider)` method. +By default, the formatting of numeric values is culture-sensitive. If you don't specify a culture when you call a formatting method, the formatting conventions of the current culture are used. This is illustrated in the following example, which changes the current culture four times and then calls the method. In each case, the result string reflects the formatting conventions of the current culture. This is because the `ToString` and `ToString(String)` methods wrap calls to each numeric type's `ToString(String, IFormatProvider)` method. [!code-csharp[Conceptual.Formatting.Overview#19](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/culturespecific3.cs#19)] [!code-vb[Conceptual.Formatting.Overview#19](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/culturespecific3.vb#19)] @@ -259,7 +259,7 @@ The following example uses objects ### Culture-sensitive formatting of date and time values -By default, the formatting of date and time values is culture-sensitive. If you do not specify a culture when you call a formatting method, the formatting conventions of the current culture are used. This is illustrated in the following example, which changes the current culture four times and then calls the method. In each case, the result string reflects the formatting conventions of the current culture. This is because the , , , and methods wrap calls to the and methods. +By default, the formatting of date and time values is culture-sensitive. If you don't specify a culture when you call a formatting method, the formatting conventions of the current culture are used. This is illustrated in the following example, which changes the current culture four times and then calls the method. In each case, the result string reflects the formatting conventions of the current culture. This is because the , , , and methods wrap calls to the and methods. [!code-csharp[Conceptual.Formatting.Overview#17](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/culturespecific1.cs#17)] [!code-vb[Conceptual.Formatting.Overview#17](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/culturespecific1.vb#17)] @@ -319,14 +319,14 @@ For more information about composite formatting, see [Composite Formatting](comp Two composite formatting methods, and , include a format provider parameter that supports custom formatting. When either of these formatting methods is called, it passes a object that represents an interface to the format provider's method. The method is then responsible for returning the implementation that provides custom formatting. -The interface has a single method, , that is called automatically by a composite formatting method, once for each format item in a composite format string. The method has three parameters: a format string, which represents the `formatString` argument in a format item, an object to format, and an object that provides formatting services. Typically, the class that implements also implements , so this last parameter is a reference to the custom formatting class itself. The method returns a custom formatted string representation of the object to be formatted. If the method cannot format the object, it should return a null reference (`Nothing` in Visual Basic). +The interface has a single method, , that is called automatically by a composite formatting method, once for each format item in a composite format string. The method has three parameters: a format string, which represents the `formatString` argument in a format item, an object to format, and an object that provides formatting services. Typically, the class that implements also implements , so this last parameter is a reference to the custom formatting class itself. The method returns a custom formatted string representation of the object to be formatted. If the method can't format the object, it should return a null reference (`Nothing` in Visual Basic). The following example provides an implementation named `ByteByByteFormatter` that displays integer values as a sequence of two-digit hexadecimal values followed by a space. [!code-csharp[Conceptual.Formatting.Overview#15](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/icustomformatter1.cs#15)] [!code-vb[Conceptual.Formatting.Overview#15](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/icustomformatter1.vb#15)] -The following example uses the `ByteByByteFormatter` class to format integer values. Note that the method is called more than once in the second method call, and that the default provider is used in the third method call because the .`ByteByByteFormatter.Format` method does not recognize the "N0" format string and returns a null reference (`Nothing` in Visual Basic). +The following example uses the `ByteByByteFormatter` class to format integer values. Note that the method is called more than once in the second method call, and that the default provider is used in the third method call because the .`ByteByByteFormatter.Format` method doesn't recognize the "N0" format string and returns a null reference (`Nothing` in Visual Basic). [!code-csharp[Conceptual.Formatting.Overview#16](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/icustomformatter1.cs#16)] [!code-vb[Conceptual.Formatting.Overview#16](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/icustomformatter1.vb#16)] diff --git a/docs/standard/exceptions/best-practices-for-exceptions.md b/docs/standard/exceptions/best-practices-for-exceptions.md index d55d3cf6942ee..630c1eadc0f35 100644 --- a/docs/standard/exceptions/best-practices-for-exceptions.md +++ b/docs/standard/exceptions/best-practices-for-exceptions.md @@ -61,7 +61,7 @@ If the performance cost of exceptions is prohibitive, some .NET library methods It's better to catch instead of , which derives from `OperationCanceledException`, when you call an asynchronous method. Many asynchronous methods throw an exception if cancellation is requested. These exceptions enable execution to be efficiently halted and the callstack to be unwound once a cancellation request is observed. -Asynchronous methods store exceptions that are thrown during execution in the task they return. If an exception is stored into the returned task, that exception will be thrown when the task is awaited. Usage exceptions, such as , are still thrown synchronously. For more information, see [Asynchronous exceptions](../../csharp/asynchronous-programming/index.md#handle-asynchronous-exceptions). +Asynchronous methods store exceptions that are thrown during execution in the task they return. If an exception is stored into the returned task, that exception is thrown when the task is awaited. Usage exceptions, such as , are still thrown synchronously. For more information, see [Asynchronous exceptions](../../csharp/asynchronous-programming/index.md#handle-asynchronous-exceptions). ### Design classes so that exceptions can be avoided @@ -178,7 +178,7 @@ catch (FileNotFoundException e) Console.WriteLine("I was here."); -if (edi is not null) +if (edi isn't null) edi.Throw(); ``` @@ -266,7 +266,7 @@ Write clear sentences and include ending punctuation. Each sentence in the strin ### Place throw statements well -Place throw statements where the stack trace will be helpful. The stack trace begins at the statement where the exception is thrown and ends at the `catch` statement that catches the exception. +Place throw statements where the stack trace is helpful. The stack trace begins at the statement where the exception is thrown and ends at the `catch` statement that catches the exception. ### Don't raise exceptions in finally clauses diff --git a/docs/standard/garbage-collection/fundamentals.md b/docs/standard/garbage-collection/fundamentals.md index ef3da60bfaa8d..09f4f7dbc5a5a 100644 --- a/docs/standard/garbage-collection/fundamentals.md +++ b/docs/standard/garbage-collection/fundamentals.md @@ -51,7 +51,7 @@ The following list summarizes important CLR memory concepts: | Reserved | The block of memory is available for your use and can't be used for any other allocation request. However, you can't store data to this memory block until it's committed. | | Committed | The block of memory is assigned to physical storage. | -- Virtual address space can get fragmented, which means that there are free blocks known as holes in the address space. When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy the allocation request. Even if you have 2 GB of free space, an allocation that requires 2 GB will be unsuccessful unless all of that free space is in a single address block. +- Virtual address space can get fragmented, which means that there are free blocks known as holes in the address space. When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy the allocation request. Even if you have 2 GB of free space, an allocation that requires 2 GB is unsuccessful unless all of that free space is in a single address block. - You can run out of memory if there isn't enough virtual address space to reserve or physical space to commit. @@ -59,7 +59,7 @@ The following list summarizes important CLR memory concepts: ### Memory allocation -When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the runtime allocates memory for it in the address space immediately following the first object. As long as address space is available, the runtime continues to allocate space for new objects in this manner. +When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap is allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the runtime allocates memory for it in the address space immediately following the first object. As long as address space is available, the runtime continues to allocate space for new objects in this manner. Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it's almost as fast as allocating memory from the stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects quickly. @@ -172,7 +172,7 @@ A garbage collection has the following phases: - A marking phase that finds and creates a list of all live objects. -- A relocating phase that updates the references to the objects that will be compacted. +- A relocating phase that updates the references to the objects that is compacted. - A compacting phase that reclaims the space occupied by the dead objects and compacts the surviving objects. The compacting phase moves objects that have survived a garbage collection towards the older end of the segment. diff --git a/docs/standard/garbage-collection/implementing-dispose.md b/docs/standard/garbage-collection/implementing-dispose.md index c37936a38a765..844620c904934 100644 --- a/docs/standard/garbage-collection/implementing-dispose.md +++ b/docs/standard/garbage-collection/implementing-dispose.md @@ -128,7 +128,7 @@ Here's an example of the general pattern for implementing the dispose pattern fo :::code language="vb" source="../../../samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/derived1.vb"::: > [!NOTE] -> The previous example uses a object to illustrate the pattern; any object derived from could be used instead. Note that the example does not properly instantiate its object. +> The previous example uses a object to illustrate the pattern; any object derived from could be used instead. Note that the example doesn't properly instantiate its object. Here's the general pattern for implementing the dispose pattern for a derived class that overrides : @@ -154,7 +154,7 @@ The following code demonstrates how to handle unmanaged resources by implementin > The behavior of the `DisposableBaseWithSafeHandle` class is equivalent to the behavior of the [`DisposableBaseWithFinalizer` class in a previous example](#base-class-with-unmanaged-resources), however the approach demonstrated here is safer: > > - There is no need to implement a finalizer, because will take care of finalization. -> - There is no need for synchronization to guarantee thread safety. Even though there is a race condition in the `Dispose` implementation of `DisposableBaseWithSafeHandle`, guarantees that will be called only once. +> - There is no need for synchronization to guarantee thread safety. Even though there is a race condition in the `Dispose` implementation of `DisposableBaseWithSafeHandle`, guarantees that is called only once. ### Built-in safe handles in .NET diff --git a/docs/standard/io/file-path-formats.md b/docs/standard/io/file-path-formats.md index 53cd29f31e1a2..904d59b868007 100644 --- a/docs/standard/io/file-path-formats.md +++ b/docs/standard/io/file-path-formats.md @@ -37,7 +37,7 @@ If all three components are present, the path is absolute. If no volume or drive > [!IMPORTANT] > Note the difference between the last two paths. Both specify the optional volume specifier (`C:` in both cases), but the first begins with the root of the specified volume, whereas the second does not. As result, the first is an absolute path from the root directory of drive `C:`, whereas the second is a relative path from the current directory of drive `C:`. Use of the second form when the first is intended is a common source of bugs that involve Windows file paths. -You can determine whether a file path is fully qualified (that is, if the path is independent of the current directory and does not change when the current directory changes) by calling the method. Note that such a path can include relative directory segments (`.` and `..`) and still be fully qualified if the resolved path always points to the same location. +You can determine whether a file path is fully qualified (that is, if the path is independent of the current directory and doesn't change when the current directory changes) by calling the method. Note that such a path can include relative directory segments (`.` and `..`) and still be fully qualified if the resolved path always points to the same location. The following example illustrates the difference between absolute and relative paths. It assumes that the directory `D:\FY2018\` exists, and that you haven't set any current directory for `D:\` from the command prompt before running the example. @@ -95,7 +95,7 @@ The DOS device path consists of the following components: For device UNCs, the server/share portion forms the volume. For example, in `\\?\server1\utilities\\filecomparer\`, the server/share portion is `server1\utilities`. This is significant when calling a method such as with relative directory segments; it is never possible to navigate past the volume. -DOS device paths are fully qualified by definition and cannot begin with a relative directory segment (`.` or `..`). Current directories never enter into their usage. +DOS device paths are fully qualified by definition and can't begin with a relative directory segment (`.` or `..`). Current directories never enter into their usage. ## Example: Ways to refer to the same file @@ -138,11 +138,11 @@ Prior to Windows 11, a path that begins with a legacy device name is always inte ### Apply the current directory -If a path isn't fully qualified, Windows applies the current directory to it. UNCs and device paths do not have the current directory applied. Neither does a full drive with separator `C:\`. +If a path isn't fully qualified, Windows applies the current directory to it. UNCs and device paths don't have the current directory applied. Neither does a full drive with separator `C:\`. If the path starts with a single component separator, the drive from the current directory is applied. For example, if the file path is `\utilities` and the current directory is `C:\temp\`, normalization produces `C:\utilities`. -If the path starts with a drive letter, volume separator, and no component separator, the last current directory set from the command shell for the specified drive is applied. If the last current directory was not set, the drive alone is applied. For example, if the file path is `D:sources`, the current directory is `C:\Documents\`, and the last current directory on drive D: was `D:\sources\`, the result is `D:\sources\sources`. These "drive relative" paths are a common source of program and script logic errors. Assuming that a path beginning with a letter and a colon isn't relative is obviously not correct. +If the path starts with a drive letter, volume separator, and no component separator, the last current directory set from the command shell for the specified drive is applied. If the last current directory wasn't set, the drive alone is applied. For example, if the file path is `D:sources`, the current directory is `C:\Documents\`, and the last current directory on drive D: was `D:\sources\`, the result is `D:\sources\sources`. These "drive relative" paths are a common source of program and script logic errors. Assuming that a path beginning with a letter and a colon isn't relative is obviously not correct. If the path starts with something other than a separator, the current drive and current directory are applied. For example, if the path is `filecompare` and the current directory is `C:\utilities\`, the result is `C:\utilities\filecompare\`. @@ -170,7 +170,7 @@ As the path is processed, any components or segments that are composed of a sing Along with the runs of separators and relative segments removed earlier, some additional characters are removed during normalization: -- If a segment ends in a single period, that period is removed. (A segment of a single or double period is normalized in the previous step. A segment of three or more periods is not normalized and is actually a valid file/directory name.) +- If a segment ends in a single period, that period is removed. (A segment of a single or double period is normalized in the previous step. A segment of three or more periods isn't normalized and is actually a valid file/directory name.) - If the path doesn't end in a separator, all trailing periods and spaces (U+0020) are removed. If the last segment is simply a single or double period, it falls under the relative components rule above. @@ -192,7 +192,7 @@ Why would you want to skip normalization? There are three major reasons: 1. On .NET Framework only, to skip the `MAX_PATH` check for path length to allow for paths that are greater than 259 characters. Most APIs allow this, with some exceptions. > [!NOTE] -> .NET Core and .NET 5+ handles long paths implicitly and does not perform a `MAX_PATH` check. The `MAX_PATH` check applies only to .NET Framework. +> .NET Core and .NET 5+ handles long paths implicitly and doesn't perform a `MAX_PATH` check. The `MAX_PATH` check applies only to .NET Framework. Skipping normalization and max path checks is the only difference between the two device path syntaxes; they are otherwise identical. Be careful with skipping normalization, since you can easily create paths that are difficult for "normal" applications to deal with. diff --git a/docs/standard/parallel-programming/dataflow-task-parallel-library.md b/docs/standard/parallel-programming/dataflow-task-parallel-library.md index 232d1c98f0b88..5d9413f527ab0 100644 --- a/docs/standard/parallel-programming/dataflow-task-parallel-library.md +++ b/docs/standard/parallel-programming/dataflow-task-parallel-library.md @@ -46,20 +46,20 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th The dataflow programming model is related to the concept of *message passing*, where independent components of a program communicate with one another by sending messages. One way to propagate messages among application components is to call the (synchronous) and (asynchronous) methods to send messages to target dataflow blocks, and the , , and methods to receive messages from source blocks. You can combine these methods with dataflow pipelines or networks by sending input data to the head node (a target block), and by receiving output data from the terminal node of the pipeline or the terminal nodes of the network (one or more source blocks). You can also use the method to read from the first of the provided sources that has data available and perform action on that data. - Source blocks offer data to target blocks by calling the method. The target block responds to an offered message in one of three ways: it can accept the message, decline the message, or postpone the message. When the target accepts the message, the method returns . When the target declines the message, the method returns . When the target requires that it no longer receives any messages from the source, returns . The predefined source block types do not offer messages to linked targets after such a return value is received, and they automatically unlink from such targets. + Source blocks offer data to target blocks by calling the method. The target block responds to an offered message in one of three ways: it can accept the message, decline the message, or postpone the message. When the target accepts the message, the method returns . When the target declines the message, the method returns . When the target requires that it no longer receives any messages from the source, returns . The predefined source block types don't offer messages to linked targets after such a return value is received, and they automatically unlink from such targets. When a target block postpones the message for later use, the method returns . A target block that postpones a message can later call the method to try to reserve the offered message. At this point, the message is either still available and can be used by the target block, or the message has been taken by another target. When the target block later requires the message or no longer needs the message, it calls the or method, respectively. Message reservation is typically used by the dataflow block types that operate in non-greedy mode. Non-greedy mode is explained later in this document. Instead of reserving a postponed message, a target block can also use the method to attempt to directly consume the postponed message. ### Dataflow Block Completion - Dataflow blocks also support the concept of *completion*. A dataflow block that is in the completed state does not perform any further work. Each dataflow block has an associated object, known as a *completion task*, that represents the completion status of the block. Because you can wait for a object to finish, by using completion tasks, you can wait for one or more terminal nodes of a dataflow network to finish. The interface defines the method, which informs the dataflow block of a request for it to complete, and the property, which returns the completion task for the dataflow block. Both and inherit the interface. + Dataflow blocks also support the concept of *completion*. A dataflow block that is in the completed state doesn't perform any further work. Each dataflow block has an associated object, known as a *completion task*, that represents the completion status of the block. Because you can wait for a object to finish, by using completion tasks, you can wait for one or more terminal nodes of a dataflow network to finish. The interface defines the method, which informs the dataflow block of a request for it to complete, and the property, which returns the completion task for the dataflow block. Both and inherit the interface. There are two ways to determine whether a dataflow block completed without error, encountered one or more errors, or was canceled. The first way is to call the method on the completion task in a `try`-`catch` block (`Try`-`Catch` in Visual Basic). The following example creates an object that throws if its input value is less than zero. is thrown when this example calls on the completion task. The is accessed through the property of the object. [!code-csharp[TPLDataflow_Overview#10](../../../samples/snippets/csharp/VS_Snippets_Misc/tpldataflow_overview/cs/program.cs#10)] [!code-vb[TPLDataflow_Overview#10](../../../samples/snippets/visualbasic/VS_Snippets_Misc/tpldataflow_overview/vb/program.vb#10)] - This example demonstrates the case in which an exception goes unhandled in the delegate of an execution dataflow block. We recommend that you handle exceptions in the bodies of such blocks. However, if you are unable to do so, the block behaves as though it was canceled and does not process incoming messages. + This example demonstrates the case in which an exception goes unhandled in the delegate of an execution dataflow block. We recommend that you handle exceptions in the bodies of such blocks. However, if you are unable to do so, the block behaves as though it was canceled and doesn't process incoming messages. When a dataflow block is canceled explicitly, the object contains in the property. For more information about dataflow cancellation, see [Enabling Cancellation](#enabling-cancellation) section. @@ -93,7 +93,7 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th The class is useful when you must pass multiple messages to another component, but that component needs only the most recent value. This class is also useful when you want to broadcast a message to multiple components. - The following basic example posts a value to a object and then reads that value back from that object several times. Because values are not removed from objects after they are read, the same value is available every time. + The following basic example posts a value to a object and then reads that value back from that object several times. Because values aren't removed from objects after they are read, the same value is available every time. [!code-csharp[TPLDataflow_Overview#2](../../../samples/snippets/csharp/VS_Snippets_Misc/tpldataflow_overview/cs/program.cs#2)] [!code-vb[TPLDataflow_Overview#2](../../../samples/snippets/visualbasic/VS_Snippets_Misc/tpldataflow_overview/vb/program.vb#2)] @@ -102,7 +102,7 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th #### WriteOnceBlock\ - The class resembles the class, except that a object can be written to one time only. You can think of as being similar to the C# [readonly](../../csharp/language-reference/keywords/readonly.md) ([ReadOnly](../../visual-basic/language-reference/modifiers/readonly.md) in Visual Basic) keyword, except that a object becomes immutable after it receives a value instead of at construction. Like the class, when a target receives a message from a object, that message is not removed from that object. Therefore, multiple targets receive a copy of the message. The class is useful when you want to propagate only the first of multiple messages. + The class resembles the class, except that a object can be written to one time only. You can think of as being similar to the C# [readonly](../../csharp/language-reference/keywords/readonly.md) ([ReadOnly](../../visual-basic/language-reference/modifiers/readonly.md) in Visual Basic) keyword, except that a object becomes immutable after it receives a value instead of at construction. Like the class, when a target receives a message from a object, that message isn't removed from that object. Therefore, multiple targets receive a copy of the message. The class is useful when you want to propagate only the first of multiple messages. The following basic example posts multiple values to a object and then reads the value back from that object. Because a object can be written to one time only, after a object receives a message, it discards subsequent messages. @@ -170,7 +170,7 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th #### BatchBlock\ - The class combines sets of input data, which are known as batches, into arrays of output data. You specify the size of each batch when you create a object. When the object receives the specified count of input elements, it asynchronously propagates out an array that contains those elements. If a object is set to the completed state but does not contain enough elements to form a batch, it propagates out a final array that contains the remaining input elements. + The class combines sets of input data, which are known as batches, into arrays of output data. You specify the size of each batch when you create a object. When the object receives the specified count of input elements, it asynchronously propagates out an array that contains those elements. If a object is set to the completed state but doesn't contain enough elements to form a batch, it propagates out a final array that contains the remaining input elements. The class operates in either *greedy* or *non-greedy* mode. In greedy mode, which is the default, a object accepts every message that it is offered and propagates out an array after it receives the specified count of elements. In non-greedy mode, a object postpones all incoming messages until enough sources have offered messages to the block to form a batch. Greedy mode typically performs better than non-greedy mode because it requires less processing overhead. However, you can use non-greedy mode when you must coordinate consumption from multiple sources in an atomic fashion. Specify non-greedy mode by setting to `False` in the `dataflowBlockOptions` parameter in the constructor. @@ -183,7 +183,7 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th #### JoinBlock\ - The and classes collect input elements and propagate out or objects that contain those elements. The and classes do not inherit from . Instead, they provide properties, , , and , that implement . + The and classes collect input elements and propagate out or objects that contain those elements. The and classes don't inherit from . Instead, they provide properties, , , and , that implement . Like , and operate in either greedy or non-greedy mode. In greedy mode, which is the default, a or object accepts every message that it is offered and propagates out a tuple after each of its targets receives at least one message. In non-greedy mode, a or object postpones all incoming messages until all targets have been offered the data that is required to create a tuple. At this point, the block engages in a two-phase commit protocol to atomically retrieve all required items from the sources. This postponement makes it possible for another entity to consume the data in the meantime, to allow the overall system to make forward progress. @@ -250,7 +250,7 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th ### Enabling Cancellation - The TPL provides a mechanism that enables tasks to coordinate cancellation in a cooperative manner. To enable dataflow blocks to participate in this cancellation mechanism, set the property. When this object is set to the canceled state, all dataflow blocks that monitor this token finish execution of their current item but do not start processing subsequent items. These dataflow blocks also clear any buffered messages, release connections to any source and target blocks, and transition to the canceled state. By transitioning to the canceled state, the property has the property set to , unless an exception occurred during processing. In that case, is set to . + The TPL provides a mechanism that enables tasks to coordinate cancellation in a cooperative manner. To enable dataflow blocks to participate in this cancellation mechanism, set the property. When this object is set to the canceled state, all dataflow blocks that monitor this token finish execution of their current item but don't start processing subsequent items. These dataflow blocks also clear any buffered messages, release connections to any source and target blocks, and transition to the canceled state. By transitioning to the canceled state, the property has the property set to , unless an exception occurred during processing. In that case, is set to . For an example that demonstrates how to use cancellation in a Windows Forms application, see [How to: Cancel a Dataflow Block](how-to-cancel-a-dataflow-block.md). For more information about cancellation in the TPL, see [Task Cancellation](task-cancellation.md). @@ -258,7 +258,7 @@ The Task Parallel Library (TPL) provides dataflow components to help increase th Several grouping dataflow block types can operate in either *greedy* or *non-greedy* mode. By default, the predefined dataflow block types operate in greedy mode. - For join block types such as , greedy mode means that the block immediately accepts data even if the corresponding data with which to join is not yet available. Non-greedy mode means that the block postpones all incoming messages until one is available on each of its targets to complete the join. If any of the postponed messages are no longer available, the join block releases all postponed messages and restarts the process. For the class, greedy and non-greedy behavior is similar, except that under non-greedy mode, a object postpones all incoming messages until enough are available from distinct sources to complete a batch. + For join block types such as , greedy mode means that the block immediately accepts data even if the corresponding data with which to join isn't yet available. Non-greedy mode means that the block postpones all incoming messages until one is available on each of its targets to complete the join. If any of the postponed messages are no longer available, the join block releases all postponed messages and restarts the process. For the class, greedy and non-greedy behavior is similar, except that under non-greedy mode, a object postpones all incoming messages until enough are available from distinct sources to complete a batch. To specify non-greedy mode for a dataflow block, set to `False`. For an example that demonstrates how to use non-greedy mode to enable multiple join blocks to share a data source more efficiently, see [How to: Use JoinBlock to Read Data From Multiple Sources](how-to-use-joinblock-to-read-data-from-multiple-sources.md). diff --git a/docs/standard/parallel-programming/task-based-asynchronous-programming.md b/docs/standard/parallel-programming/task-based-asynchronous-programming.md index ad55956b634ad..bc3502d6ebf05 100644 --- a/docs/standard/parallel-programming/task-based-asynchronous-programming.md +++ b/docs/standard/parallel-programming/task-based-asynchronous-programming.md @@ -175,7 +175,7 @@ For an example that shows exception handling, see [Exception Handling](exception Some overloads let you specify a time-out, and others take an additional as an input parameter so that the wait itself can be canceled either programmatically or in response to user input. -When you wait for a task, you implicitly wait for all children of that task that were created by using the option. returns immediately if the task has already completed. A method will throw any exceptions raised by a task, even if the method was called after the task completed. +When you wait for a task, you implicitly wait for all children of that task that were created by using the option. returns immediately if the task has already completed. A method throws any exceptions raised by a task, even if the method was called after the task completed. ## Composing tasks @@ -239,7 +239,7 @@ The class provides static methods that - To encapsulate Asynchronous Programming Model `BeginX` and `EndX` methods in a or instance, use the methods. For more information, see [TPL and Traditional .NET Framework Asynchronous Programming](tpl-and-traditional-async-programming.md). -The default can be accessed as a static property on the class or class. You can also instantiate a directly and specify various options that include a , a option, a option, or a . Whatever options are specified when you create the task factory will be applied to all tasks that it creates unless the is created by using the enumeration, in which case the task's options override those of the task factory. +The default can be accessed as a static property on the class or class. You can also instantiate a directly and specify various options that include a , a option, a option, or a . Whatever options are specified when you create the task factory is applied to all tasks that it creates unless the is created by using the enumeration, in which case the task's options override those of the task factory. ## Tasks without delegates diff --git a/docs/standard/serialization/system-text-json/converters-how-to.md b/docs/standard/serialization/system-text-json/converters-how-to.md index 7a788ed51bed0..3483a6e28d02b 100644 --- a/docs/standard/serialization/system-text-json/converters-how-to.md +++ b/docs/standard/serialization/system-text-json/converters-how-to.md @@ -87,7 +87,7 @@ The `Enum` type is similar to an open generic type: a converter for `Enum` has t ## The use of `Utf8JsonReader` in the `Read` method -If your converter is converting a JSON object, the `Utf8JsonReader` will be positioned on the begin object token when the `Read` method begins. You must then read through all the tokens in that object and exit the method with the reader positioned on **the corresponding end object token**. If you read beyond the end of the object, or if you stop before reaching the corresponding end token, you get a `JsonException` exception indicating that: +If your converter is converting a JSON object, the `Utf8JsonReader` is positioned on the begin object token when the `Read` method begins. You must then read through all the tokens in that object and exit the method with the reader positioned on **the corresponding end object token**. If you read beyond the end of the object, or if you stop before reaching the corresponding end token, you get a `JsonException` exception indicating that: > The converter 'ConverterName' read too much or not enough. @@ -103,7 +103,7 @@ If you throw a `JsonException` without a message, the serializer creates a messa ```output Unhandled exception. System.Text.Json.JsonException: -The JSON value could not be converted to System.Object. +The JSON value couldn't be converted to System.Object. Path: $.Date | LineNumber: 1 | BytePositionInLine: 37. ``` @@ -121,9 +121,9 @@ Path: $.TemperatureRanges | LineNumber: 4 | BytePositionInLine: 24 ### When to throw which exception type -When the JSON payload contains tokens that are not valid for the type being deserialized, throw a `JsonException`. +When the JSON payload contains tokens that aren't valid for the type being deserialized, throw a `JsonException`. -When you want to disallow certain types, throw a `NotSupportedException`. This exception is what the serializer automatically throws for types that are not supported. For example, `System.Type` is not supported for security reasons, so an attempt to deserialize it results in a `NotSupportedException`. +When you want to disallow certain types, throw a `NotSupportedException`. This exception is what the serializer automatically throws for types that aren't supported. For example, `System.Type` isn't supported for security reasons, so an attempt to deserialize it results in a `NotSupportedException`. You can throw other exceptions as needed, but they don't automatically include JSON path information. @@ -239,7 +239,7 @@ Suppose, for example, you have a `Person` abstract base class, with `Employee` a The following code shows a base class, two derived classes, and a custom converter for them. The converter uses a discriminator property to do polymorphic deserialization. The type discriminator isn't in the class definitions but is created during serialization and is read during deserialization. > [!IMPORTANT] -> The example code requires JSON object name/value pairs to stay in order, which is not a standard requirement of JSON. +> The example code requires JSON object name/value pairs to stay in order, which isn't a standard requirement of JSON. :::code language="csharp" source="snippets/how-to/csharp/Person.cs" id="Person"::: @@ -312,8 +312,8 @@ By default, the serializer handles null values as follows: * For reference types and types: - * It does not pass `null` to custom converters on serialization. - * It does not pass `JsonTokenType.Null` to custom converters on deserialization. + * It doesn't pass `null` to custom converters on serialization. + * It doesn't pass `JsonTokenType.Null` to custom converters on deserialization. * It returns a `null` instance on deserialization. * It writes `null` directly with the writer on serialization. From 19ace24a7c39e58f1bb12c8efa7c3e68bb27eb8a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:14:27 +0000 Subject: [PATCH 15/30] Second editing pass: Fix remaining would/should instances and apply additional contractions Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/extensions/dependency-injection-guidelines.md | 4 ++-- docs/core/extensions/dependency-injection.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/extensions/dependency-injection-guidelines.md b/docs/core/extensions/dependency-injection-guidelines.md index 9a61a8bd044e1..b813f82b612ff 100644 --- a/docs/core/extensions/dependency-injection-guidelines.md +++ b/docs/core/extensions/dependency-injection-guidelines.md @@ -92,7 +92,7 @@ The app requires an instance with a transient lifetime **Solution** -Use the factory pattern to create an instance outside of the parent scope. In this situation, the app would generally have a `Create` method that calls the final type's constructor directly. If the final type has other dependencies, the factory can: +Use the factory pattern to create an instance outside of the parent scope. In this situation, the app generally has a `Create` method that calls the final type's constructor directly. If the final type has other dependencies, the factory can: - Receive an in its constructor. - Use to instantiate the instance outside of the container, while using the container for its dependencies. @@ -209,7 +209,7 @@ In the preceding code, `Foo` is registered as a singleton and `Bar` is scoped - :::code language="csharp" source="snippets/configuration/di-anti-patterns/Foo.cs"::: -The `Foo` object requires a `Bar` object, and since `Foo` is a singleton, and `Bar` is scoped - this is a misconfiguration. As is, `Foo` would only be instantiated once, and it would hold onto `Bar` for its lifetime, which is longer than the intended scoped lifetime of `Bar`. You should consider validating scopes, by passing `validateScopes: true` to the . When you validate the scopes, you'd get an with a message similar to "Cannot consume scoped service 'Bar' from singleton 'Foo'.". +The `Foo` object requires a `Bar` object, and since `Foo` is a singleton, and `Bar` is scoped - this is a misconfiguration. As is, `Foo` is only instantiated once, and it holds onto `Bar` for its lifetime, which is longer than the intended scoped lifetime of `Bar`. Consider validating scopes by passing `validateScopes: true` to the . When you validate the scopes, you get an with a message similar to "Cannot consume scoped service 'Bar' from singleton 'Foo'.". For more information, see [Scope validation](dependency-injection.md#scope-validation). diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md index b1f52ac1b1547..7d39ec5fa93ec 100644 --- a/docs/core/extensions/dependency-injection.md +++ b/docs/core/extensions/dependency-injection.md @@ -174,7 +174,7 @@ public class ExampleService ``` > [!WARNING] -> The `ExampleService` code with ambiguous DI-resolvable type parameters would throw an exception. Do **not** do this—it's intended to show what is meant by "ambiguous DI-resolvable types". +> The `ExampleService` code with ambiguous DI-resolvable type parameters throws an exception. **Don't** do this—it's intended to show what is meant by "ambiguous DI-resolvable types". In the preceding example, there are three constructors. The first constructor is parameterless and requires no services from the service provider. Assume that both logging and options have been added to the DI container and are DI-resolvable services. When the DI container attempts to resolve the `ExampleService` type, it throws an exception, as the two constructors are ambiguous. @@ -325,7 +325,7 @@ services.AddSingleton(); services.TryAddSingleton(); ``` -The `TryAddSingleton` has no effect, as it was already added and the "try" fails. The `ExampleService` would assert this: +The `TryAddSingleton` has no effect, as it was already added and the "try" fails. The `ExampleService` asserts this: ```csharp public class ExampleService From 72d56f4352921152d4640e2d6ec5a5be30f56129 Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Wed, 22 Oct 2025 22:44:07 -0700 Subject: [PATCH 16/30] edit pass --- .../extensions/dependency-injection-usage.md | 10 +++--- docs/core/extensions/dependency-injection.md | 20 ++++++------ .../extensions/logger-message-generator.md | 32 +++++++++---------- docs/core/extensions/logging-providers.md | 10 +++--- docs/core/extensions/logging.md | 10 +++--- docs/core/get-started.md | 6 ++-- .../unit-testing-csharp-with-mstest.md | 8 ++--- .../testing/unit-testing-csharp-with-nunit.md | 10 +++--- docs/core/tools/telemetry.md | 3 +- docs/core/versions/selection.md | 14 ++++---- .../code-analysis/code-style-rule-options.md | 2 +- .../networking/sockets/socket-services.md | 6 ++-- docs/standard/assembly/index.md | 2 +- docs/standard/base-types/formatting-types.md | 28 ++++++++-------- .../base-types/regular-expressions.md | 4 +-- docs/standard/clr.md | 2 +- .../best-practices-for-exceptions.md | 12 +++---- 17 files changed, 89 insertions(+), 90 deletions(-) diff --git a/docs/core/extensions/dependency-injection-usage.md b/docs/core/extensions/dependency-injection-usage.md index 2fc80b1099ec0..57b90f8d723c3 100644 --- a/docs/core/extensions/dependency-injection-usage.md +++ b/docs/core/extensions/dependency-injection-usage.md @@ -40,7 +40,7 @@ Your new console app project file should resemble the following: ## Add interfaces -In this sample app, you'll learn how dependency injection handles service lifetime. You'll create several interfaces that represent different service lifetimes. Add the following interfaces to the project root directory: +In this sample app, you learn how dependency injection handles service lifetime. You create several interfaces that represent different service lifetimes. Add the following interfaces to the project root directory: *IReportServiceLifetime.cs* @@ -81,7 +81,7 @@ The example implementations all initialize their `Id` property with the result o :::code source="snippets/configuration/console-di/ExampleSingletonService.cs"::: -Each implementation is defined as `internal sealed` and implements its corresponding interface. They're not required to be `internal` or `sealed`, however, it's common to treat implementations as `internal` to avoid leaking implementation types to external consumers. Furthermore, since each type won't be extended, it's marked as `sealed`. For example, `ExampleSingletonService` implements `IExampleSingletonService`. +Each implementation is defined as `internal sealed` and implements its corresponding interface. They're not required to be `internal` or `sealed`, however, it's common to treat implementations as `internal` to avoid leaking implementation types to external consumers. Furthermore, since each type isn't extended, it's marked as `sealed`. For example, `ExampleSingletonService` implements `IExampleSingletonService`. ## Add a service that requires DI @@ -101,7 +101,7 @@ Update *Program.cs* with the following code: Each `services.Add{LIFETIME}<{SERVICE}>` extension method adds (and potentially configures) services. We recommend that apps follow this convention. Don't place extension methods in the namespace unless you're authoring an official Microsoft package. Extension methods that are defined within the `Microsoft.Extensions.DependencyInjection` namespace: -- Are displayed in [IntelliSense](/visualstudio/ide/using-intellisense) without requiring additional `using` directives. +- Are displayed in [IntelliSense](/visualstudio/ide/using-intellisense) without requiring more `using` directives. - Reduce the number of required `using` directives in the `Program` or `Startup` classes where these extension methods are typically called. The app: @@ -121,9 +121,9 @@ When you run the app, it displays output similar to the following: From the app output, you can see that: -- Transient services are always different, a new instance is created with every retrieval of the service. +- Transient services are always different. A new instance is created with every retrieval of the service. - Scoped services change only with a new scope, but are the same instance within a scope. -- Singleton services are always the same, a new instance is only created once. +- Singleton services are always the same. A new instance is only created once. ## See also diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md index 7d39ec5fa93ec..228ce453a313e 100644 --- a/docs/core/extensions/dependency-injection.md +++ b/docs/core/extensions/dependency-injection.md @@ -150,7 +150,7 @@ public class ExampleService } ``` -In the preceding code, assume that logging has been added and is resolvable from the service provider but the `FooService` and `BarService` types aren't. The constructor with the `ILogger` parameter resolves the `ExampleService` instance. Even though there's a constructor that defines more parameters, the `FooService` and `BarService` types aren't DI-resolvable. +In the preceding code, assume that logging is added and is resolvable from the service provider but the `FooService` and `BarService` types aren't. The constructor with the `ILogger` parameter resolves the `ExampleService` instance. Even though there's a constructor that defines more parameters, the `FooService` and `BarService` types aren't DI-resolvable. If there's ambiguity when discovering constructors, an exception is thrown. Consider this C# example service: @@ -306,7 +306,7 @@ services.AddSingleton(); This equivalency is why multiple implementations of a service can't be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they all have the same *implementation* type. -Any of the above service registration methods can be used to register multiple service instances of the same service type. In the following example, `AddSingleton` is called twice with `IMessageWriter` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMessageWriter` and adds to the previous one when multiple services are resolved via `IEnumerable`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`. +Any of the service registration methods can be used to register multiple service instances of the same service type. In the following example, `AddSingleton` is called twice with `IMessageWriter` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMessageWriter` and adds to the previous one when multiple services are resolved via `IEnumerable`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`. :::code language="csharp" source="snippets/configuration/console-di-ienumerable/Program.cs" highlight="11-16"::: @@ -314,7 +314,7 @@ The preceding sample source code registers two implementations of the `IMessageW :::code language="csharp" source="snippets/configuration/console-di-ienumerable/ExampleService.cs" highlight="7-16"::: -The `ExampleService` defines two constructor parameters; a single `IMessageWriter`, and an `IEnumerable`. The single `IMessageWriter` is the last implementation to have been registered, whereas the `IEnumerable` represents all registered implementations. +The `ExampleService` defines two constructor parameters; a single `IMessageWriter`, and an `IEnumerable`. The single `IMessageWriter` is the last implementation to be registered, whereas the `IEnumerable` represents all registered implementations. The framework also provides `TryAdd{LIFETIME}` extension methods, which register the service only if there isn't already an implementation registered. @@ -347,7 +347,7 @@ For more information, see: - - -The [TryAddEnumerable(ServiceDescriptor)](xref:Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddEnumerable%2A) methods register the service only if there isn't already an implementation *of the same type*. Multiple services are resolved via `IEnumerable<{SERVICE}>`. When registering services, add an instance if one of the same types hasn't already been added. Library authors use `TryAddEnumerable` to avoid registering multiple copies of an implementation in the container. +The [TryAddEnumerable(ServiceDescriptor)](xref:Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddEnumerable%2A) methods register the service only if there isn't already an implementation *of the same type*. Multiple services are resolved via `IEnumerable<{SERVICE}>`. When registering services, add an instance if one of the same types wasn't already added. Library authors use `TryAddEnumerable` to avoid registering multiple copies of an implementation in the container. In this example, the first call to `TryAddEnumerable` registers `MessageWriter` as an implementation for `IMessageWriter1`. The second call registers `MessageWriter` for `IMessageWriter2`. The third call has no effect because `IMessageWriter1` already has a registered implementation of `MessageWriter`: @@ -364,7 +364,7 @@ services.TryAddEnumerable(ServiceDescriptor.Singleton()); ``` -Service registration is generally order-independent except when registering multiple implementations of the same type. +Service registration is order-independent except when registering multiple implementations of the same type. `IServiceCollection` is a collection of objects. This example shows how to register a service by creating and adding a `ServiceDescriptor`: @@ -391,9 +391,9 @@ Services can be resolved using: Constructors can accept arguments that aren't provided by dependency injection, but the arguments must assign default values. -When services are resolved by `IServiceProvider` or `ActivatorUtilities`, constructor injection requires a *public* constructor. +When `IServiceProvider` or `ActivatorUtilities` resolve services, constructor injection requires a *public* constructor. -When services are resolved by `ActivatorUtilities`, constructor injection requires that only one applicable constructor exists. Constructor overloads are supported, but only one overload can exist whose arguments can all be fulfilled by dependency injection. +When `ActivatorUtilities` resolves services, constructor injection requires that only one applicable constructor exists. Constructor overloads are supported, but only one overload can exist whose arguments can all be fulfilled by dependency injection. ## Scope validation @@ -408,7 +408,7 @@ Scoped services are disposed by the container that created them. If a scoped ser ## Scope scenarios -The is always registered as a singleton, but the can vary based on the lifetime of the containing class. For example, if you resolve services from a scope, and any of those services take an , it'll be a scoped instance. +The is always registered as a singleton, but the can vary based on the lifetime of the containing class. For example, if you resolve services from a scope, and any of those services take an , it is a scoped instance. To achieve scoping services within implementations of , such as the , *don't* inject the service dependencies via constructor injection. Instead, inject , create a scope, then resolve dependencies from the scope to use the appropriate service lifetime. @@ -417,7 +417,7 @@ To achieve scoping services within implementations of . -- Creates an for resolving additional services. +- Creates an for resolving other services. - Resolves scoped services for consumption. - Works on processing objects and then relaying them, and finally marks them as processed. @@ -436,7 +436,7 @@ services.AddKeyedSingleton("memory"); services.AddKeyedSingleton("queue"); ``` -The `key` isn't limited to `string`, it can be any `object` you want, as long as the type correctly implements `Equals`. +The `key` isn't limited to `string`. The `key` can be any `object` you want, as long as the type correctly implements `Equals`. In the constructor of the class that uses `IMessageWriter`, you add the to specify the key of the service to resolve: diff --git a/docs/core/extensions/logger-message-generator.md b/docs/core/extensions/logger-message-generator.md index 3db052e66fc95..914133275c5e4 100644 --- a/docs/core/extensions/logger-message-generator.md +++ b/docs/core/extensions/logger-message-generator.md @@ -9,7 +9,7 @@ ai-usage: ai-assisted .NET 6 introduces the `LoggerMessageAttribute` type. This attribute is part of the `Microsoft.Extensions.Logging` namespace, and when used, it source-generates performant logging APIs. The source-generation logging support is designed to deliver a highly usable and highly performant logging solution for modern .NET applications. The auto-generated source code relies on the interface in conjunction with functionality. -The source generator is triggered when `LoggerMessageAttribute` is used on `partial` logging methods. When triggered, it is either able to autogenerate the implementation of the `partial` methods it's decorating, or produce compile-time diagnostics with hints about proper usage. The compile-time logging solution is typically considerably faster at run time than existing logging approaches. It achieves this by eliminating boxing, temporary allocations, and copies to the maximum extent possible. +The source generator is triggered when `LoggerMessageAttribute` is used on `partial` logging methods. When triggered, it's either able to autogenerate the implementation of the `partial` methods it's decorating, or produce compile-time diagnostics with hints about proper usage. The compile-time logging solution is considerably faster at run time than existing logging approaches. It achieves this by eliminating boxing, temporary allocations, and copies to the maximum extent possible. ## Basic usage @@ -41,7 +41,7 @@ public static partial class Log } ``` -You may choose to use the attribute in a non-static context as well. Consider the following example where the logging method is declared as an instance method. In this context, the logging method gets the logger by accessing an `ILogger` field in the containing class. +You can choose to use the attribute in a non-static context as well. Consider the following example where the logging method is declared as an instance method. In this context, the logging method gets the logger by accessing an `ILogger` field in the containing class. ```csharp public partial class InstanceLoggingExample @@ -74,7 +74,7 @@ public partial class InstanceLoggingExample(ILogger logger) } ``` -If there is both an `ILogger` field and a primary constructor parameter, the logging method will get the logger from the field. +If there's both an `ILogger` field and a primary constructor parameter, the logging method gets the logger from the field. Sometimes, the log level needs to be dynamic rather than statically built into the code. You can do this by omitting the log level from the attribute and instead requiring it as a parameter to the logging method. @@ -91,7 +91,7 @@ public static partial class Log } ``` -You can omit the logging message and is provided for the message. The state will contain the arguments, formatted as key-value pairs. +You can omit the logging message and is provided for the message. The state contains the arguments, formatted as key-value pairs. :::code source="snippets/logging/logger-message-generator/Program.cs"::: @@ -119,7 +119,7 @@ When using the `LoggerMessageAttribute` on logging methods, some constraints mus - Logging methods must be `partial` and return `void`. - Logging method names must *not* start with an underscore. - Parameter names of logging methods must *not* start with an underscore. -- Logging methods *cannot* be generic. +- Logging methods *can't* be generic. - If a logging method is `static`, the `ILogger` instance is required as a parameter. The code-generation model depends on code being compiled with a modern C# compiler, version 9 or later. The C# 9.0 compiler became available with .NET 5. To upgrade to a modern C# compiler, edit your project file to target C# 9.0. @@ -134,7 +134,7 @@ For more information, see [C# language versioning](../../csharp/language-referen ## Log method anatomy -The signature accepts the and optionally an , as shown below. +The signature accepts the and optionally an , as shown in the following code example. ```csharp public interface ILogger @@ -170,7 +170,7 @@ public static partial void WarningLogMethod( ``` > [!IMPORTANT] -> The warnings emitted provide details as to the correct usage of the `LoggerMessageAttribute`. In the preceding example, the `WarningLogMethod` will report a `DiagnosticSeverity.Warning` of `SYSLIB0025`. +> The warnings emitted provide details as to the correct usage of the `LoggerMessageAttribute`. In the preceding example, the `WarningLogMethod` reports a `DiagnosticSeverity.Warning` of `SYSLIB0025`. > > ```console > Don't include a template for `ex` in the logging message since it is implicitly taken care of. @@ -223,7 +223,7 @@ Consider the example logging output when using the `JsonConsole` formatter: ### Indeterminate parameter order -There are no constraints on the ordering of log method parameters. A developer could define the `ILogger` as the last parameter, although it may appear a bit awkward. +There are no constraints on the ordering of log method parameters. A developer could define the `ILogger` as the last parameter, although it might appear a bit awkward. ```csharp [LoggerMessage( @@ -238,7 +238,7 @@ static partial void LogMethod( ``` > [!TIP] -> The order of the parameters on a log method is *not* required to correspond to the order of the template placeholders. Instead, the placeholder names in the template are expected to match the parameters. Consider the following `JsonConsole` output and the order of the errors. +> The order of the parameters on a log method isn't required to correspond to the order of the template placeholders. Instead, the placeholder names in the template are expected to match the parameters. Consider the following `JsonConsole` output and the order of the errors. > > ```json > { @@ -255,7 +255,7 @@ static partial void LogMethod( > } > ``` -## Additional logging examples +## More logging examples The following samples demonstrate how to retrieve the event name, set the log level dynamically, and format logging parameters. The logging methods are: @@ -372,9 +372,9 @@ Consider the example logging output when using the `JsonConsole` formatter: When logging sensitive data, it's important to prevent accidental exposure. Even with compile-time generated logging methods, logging raw sensitive values can lead to data leaks and compliance issues. -The [Microsoft.Extensions.Telemetry](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry) library provides advanced logging and telemetry enrichment capabilities for .NET applications. It extends the logging pipeline to automatically apply redaction to classified data when writing logs. It enables you to enforce data protection policies throughout your application by integrating redaction into your logging workflow. It is built for applications needing sophisticated telemetry and logging insights. +The [Microsoft.Extensions.Telemetry](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry) library provides advanced logging and telemetry enrichment capabilities for .NET applications. It extends the logging pipeline to automatically apply redaction to classified data when writing logs. It enables you to enforce data protection policies throughout your application by integrating redaction into your logging workflow. It's built for applications needing sophisticated telemetry and logging insights. -To enable redaction, use the [Microsoft.Extensions.Compliance.Redaction](https://www.nuget.org/packages/Microsoft.Extensions.Compliance.Redaction) library. This library provides **redactors**—components that transform sensitive data (for example, by erasing, masking, or hashing it) so that it is safe to output. Redactors are selected based on **data classification**, which lets you label data according to its sensitivity (such as personal, private, or public). +To enable redaction, use the [Microsoft.Extensions.Compliance.Redaction](https://www.nuget.org/packages/Microsoft.Extensions.Compliance.Redaction) library. This library provides **redactors**—components that transform sensitive data (for example, by erasing, masking, or hashing it) so that it's safe to output. Redactors are selected based on **data classification**, which lets you label data according to its sensitivity (such as personal, private, or public). To use redaction with source-generated logging methods, you should: @@ -392,7 +392,7 @@ public static partial void LogPrivateInformation( [MyTaxonomyClassifications.Private] string SSN); ``` -You will need to have a setting similar to this: +You'll need to have a setting similar to this: ```csharp using Microsoft.Extensions.Telemetry; @@ -423,12 +423,12 @@ The output should be like this: This approach ensures that only redacted data is logged, even when using compile-time generated logging APIs. You can use different redactors for different data types or classifications, and update your redaction logic centrally. -For more details about how to classify your data, see [Data classification in .NET](data-classification.md). -For more details about redaction and redactors, see [Data redaction in .NET](data-redaction.md). +For more information about how to classify your data, see [Data classification in .NET](data-classification.md). +For more information about redaction and redactors, see [Data redaction in .NET](data-redaction.md). ## Summary -With the advent of C# source generators, writing highly performant logging APIs is much easier. Using the source generator approach has several key benefits: +With the advent of C# source generators, writing highly performant logging APIs is easier. Using the source generator approach has several key benefits: - Allows the logging structure to be preserved and enables the exact format syntax required by [Message Templates](https://messagetemplates.org). - Allows supplying alternative names for the template placeholders and using format specifiers. diff --git a/docs/core/extensions/logging-providers.md b/docs/core/extensions/logging-providers.md index 8b3fd7340768e..0fc853e002dc3 100644 --- a/docs/core/extensions/logging-providers.md +++ b/docs/core/extensions/logging-providers.md @@ -36,7 +36,7 @@ builder.Logging.ClearProviders(); builder.Logging.AddConsole(); ``` -For additional providers, see: +For other providers, see: - [Built-in logging providers](#built-in-logging-providers). - [Third-party logging providers](#third-party-logging-providers). @@ -66,7 +66,7 @@ Microsoft Extensions include the following logging providers as part of the runt - [EventSource](#event-source) - [EventLog](#windows-eventlog) -The following logging providers are shipped by Microsoft, but not as part of the runtime libraries. They must be installed as additional NuGet packages. +The following logging providers are shipped by Microsoft, but not as part of the runtime libraries. They must be installed like NuGet packages. - [AzureAppServicesFile and AzureAppServicesBlob](#azure-app-service) - [ApplicationInsights](#azure-application-insights) @@ -83,7 +83,7 @@ The `Debug` provider writes log output by using the provider data using a . @@ -158,7 +158,7 @@ await host.RunAsync(); When deployed to Azure App Service, the app uses the settings in the [App Service logs](/azure/app-service/web-sites-enable-diagnostic-log/#enable-application-logging-windows) section of the **App Service** page of the Azure portal. When the following settings are updated, the changes take effect immediately without requiring a restart or redeployment of the app. -The default location for log files is in the *D:\\home\\LogFiles\\Application* folder. Additional defaults vary by provider: +The default location for log files is in the *D:\\home\\LogFiles\\Application* folder. Other defaults vary by provider: - **Application Logging (Filesystem)**: The default filesystem file name is *diagnostics-yyyymmdd.txt*. The default file size limit is 10 MB, and the default maximum number of files retained is 2. - **Application Logging (Blob)**: The default blob name is *{app-name}/yyyy/mm/dd/hh/{guid}_applicationLog.txt*. @@ -197,7 +197,7 @@ For more information, see the following resources: If you plan to develop your own implementation of the interface and corresponding custom implementation of , consider the following points: - The method is synchronous. -- The lifetime of log state and objects should *not* be assumed. +- The lifetime of log state and objects shouldn't* be assumed. An implementation of `ILoggerProvider` creates an `ILogger` via its method. If your implementation strives to queue logging messages in a non-blocking manner, the messages should first be materialized or the object state that's used to materialize a log entry should be serialized. Doing so avoids potential exceptions from disposed objects. diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index ba1bd431b17a7..05a1aaa46a67b 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -18,7 +18,7 @@ This first example shows the basics, but it's only suitable for a trivial consol - [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) - [Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) -In the next section you see how to improve the code considering scale, performance, configuration and typical programming patterns. +In the next section you see how to improve the code considering scale, performance, configuration, and typical programming patterns. :::code language="csharp" source="snippets/logging/getting-started/Program.cs"::: @@ -44,7 +44,7 @@ Consider making these changes to the previous example when logging in a less tri :::code language="csharp" source="snippets/logging/getting-started-logger-message/Program.cs" highlight="9,12-13"::: -- The recommended practice for log category names is to use the fully qualified name of the class that's creating the log message. This helps relate log messages back to the code which produced them and offers a good level of control when filtering logs. accepts a `Type` to make this naming easy to do. +- The recommended practice for log category names is to use the fully qualified name of the class that's creating the log message. This helps relate log messages back to the code that produced them and offers a good level of control when filtering logs. accepts a `Type` to make this naming easy to do. :::code language="csharp" source="snippets/logging/getting-started-type-category-name/Program.cs" highlight="8"::: @@ -320,9 +320,9 @@ The following table lists the value | LogLevel | Value | Method | Description | |--|--|--|--| -| [Trace](xref:Microsoft.Extensions.Logging.LogLevel) | 0 | | Contain the most detailed messages. These messages may contain sensitive app data. These messages are disabled by default and should ***not*** be enabled in production. | +| [Trace](xref:Microsoft.Extensions.Logging.LogLevel) | 0 | | Contain the most detailed messages. These messages might contain sensitive app data. These messages are disabled by default and should ***not*** be enabled in production. | | [Debug](xref:Microsoft.Extensions.Logging.LogLevel) | 1 | | For debugging and development. Use with caution in production due to the high volume. | -| [Information](xref:Microsoft.Extensions.Logging.LogLevel) | 2 | | Tracks the general flow of the app. May have long-term value. | +| [Information](xref:Microsoft.Extensions.Logging.LogLevel) | 2 | | Tracks the general flow of the app. Can have long-term value. | | [Warning](xref:Microsoft.Extensions.Logging.LogLevel) | 3 | | For abnormal or unexpected events. Typically includes errors or conditions that don't cause the app to fail. | | [Error](xref:Microsoft.Extensions.Logging.LogLevel) | 4 | | For errors and exceptions that can't be handled. These messages indicate a failure in the current operation or request, not an app-wide failure. | | [Critical](xref:Microsoft.Extensions.Logging.LogLevel) | 5 | | For failures that require immediate attention. Examples: data loss scenarios, out of disk space. | @@ -437,7 +437,7 @@ Parameter values: param1, param2 ``` > [!NOTE] -> Be mindful when using multiple placeholders within a single message template, as they're ordinal-based. The names are _not_ used to align the arguments to the placeholders. +> Be mindful when using multiple placeholders within a single message template, as they're ordinal-based. The names aren't_ used to align the arguments to the placeholders. This approach lets logging providers implement [semantic or structured logging](https://github.com/NLog/NLog/wiki/How-to-use-structured-logging). The arguments themselves are passed to the logging system, not just the formatted message template. This enables logging providers to store the parameter values as fields. Consider this logger method: diff --git a/docs/core/get-started.md b/docs/core/get-started.md index b97df25ed41c2..58be4666d62f4 100644 --- a/docs/core/get-started.md +++ b/docs/core/get-started.md @@ -18,7 +18,7 @@ First, download and install the [.NET SDK](https://dotnet.microsoft.com/download Next, open a terminal such as **PowerShell**, **Command Prompt**, or **bash**. -Type these commands: +Type the following commands: ```dotnetcli dotnet new console -o sample1 @@ -26,13 +26,13 @@ cd sample1 dotnet run ``` -You should see this output: +You should see the following output: ```output Hello World! ``` -Congratulations! You've created a simple .NET application. +Congratulations! You created a simple .NET application. ## Next steps diff --git a/docs/core/testing/unit-testing-csharp-with-mstest.md b/docs/core/testing/unit-testing-csharp-with-mstest.md index 47a36ae387e66..826d07380946d 100644 --- a/docs/core/testing/unit-testing-csharp-with-mstest.md +++ b/docs/core/testing/unit-testing-csharp-with-mstest.md @@ -133,9 +133,9 @@ namespace Prime.UnitTests.Services The [TestClass attribute](xref:Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute) denotes a class that contains unit tests. The [TestMethod attribute](xref:Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute) indicates a method is a test method. -Save this file and execute [`dotnet test`](../tools/dotnet-test.md) to build the tests and the class library and then run the tests. The MSTest test runner contains the program entry point to run your tests. `dotnet test` starts the test runner using the unit test project you've created. +Save this file and execute [`dotnet test`](../tools/dotnet-test.md) to build the tests and the class library and then run the tests. The MSTest test runner contains the program entry point to run your tests. `dotnet test` starts the test runner using the unit test project you created. -Your test fails. You haven't created the implementation yet. Make this test pass by writing the simplest code in the `PrimeService` class that works: +Your test fails because you didn't create the implementation yet. Make this test pass by writing the simplest code in the `PrimeService` class that works: ```csharp public bool IsPrime(int candidate) @@ -152,7 +152,7 @@ In the *unit-testing-using-mstest* directory, run `dotnet test` again. The `dotn ## Add more features -Now that you've made one test pass, it's time to write more. There are a few other simple cases for prime numbers: 0, -1. You could add new tests with the [TestMethod attribute](xref:Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute), but that quickly becomes tedious. There are other MSTest attributes that enable you to write a suite of similar tests. A test method can execute the same code but have different input arguments. You can use the [DataRow attribute](xref:Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute) to specify values for those inputs. +Now that you made one test pass, it's time to write more. There are a few other simple cases for prime numbers: 0, -1. You could add new tests with the [TestMethod attribute](xref:Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute), but that quickly becomes tedious. There are other MSTest attributes that enable you to write a suite of similar tests. A test method can execute the same code but have different input arguments. You can use the [DataRow attribute](xref:Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute) to specify values for those inputs. Instead of creating new tests, apply these two attributes to create a single data driven test. The data driven test is a method that tests several values less than two, which is the lowest prime number. Add a new test method in *PrimeService_IsPrimeShould.cs*: @@ -166,7 +166,7 @@ if (candidate < 2) Continue to iterate by adding more tests, more theories, and more code in the main library. You have the [finished version of the tests](https://github.com/dotnet/samples/blob/main/core/getting-started/unit-testing-using-mstest/PrimeService.Tests/PrimeService_IsPrimeShould.cs) and the [complete implementation of the library](https://github.com/dotnet/samples/blob/main/core/getting-started/unit-testing-using-mstest/PrimeService/PrimeService.cs). -You've built a small library and a set of unit tests for that library. You've structured the solution so that adding new packages and tests is part of the normal workflow. You've concentrated most of your time and effort on solving the goals of the application. +You built a small library and a set of unit tests for that library. You structured the solution so that adding new packages and tests is part of the normal workflow. You concentrated most of your time and effort on solving the goals of the application. ## See also diff --git a/docs/core/testing/unit-testing-csharp-with-nunit.md b/docs/core/testing/unit-testing-csharp-with-nunit.md index e806a0d933e3b..5f35fd312de4c 100644 --- a/docs/core/testing/unit-testing-csharp-with-nunit.md +++ b/docs/core/testing/unit-testing-csharp-with-nunit.md @@ -85,7 +85,7 @@ The [dotnet new](../tools/dotnet-new.md) command creates a test project that use [!code-xml[Packages](~/samples/snippets/core/testing/unit-testing-using-nunit/csharp/PrimeService.Tests/PrimeService.Tests.csproj#Packages)] > [!NOTE] -> Prior to .NET 9, the generated code may reference older versions of the NUnit test framework. You may use [dotnet CLI](/nuget/consume-packages/install-use-packages-dotnet-cli) to update the packages. Alternatively, open the *PrimeService.Tests.csproj* file and replace the contents of the package references item group with the code above. +> Prior to .NET 9, the generated code might reference older versions of the NUnit test framework. You can use [dotnet CLI](/nuget/consume-packages/install-use-packages-dotnet-cli) to update the packages. Alternatively, open the *PrimeService.Tests.csproj* file and replace the contents of the package references item group with the code shown previously. The test project requires other packages to create and run unit tests. The `dotnet new` command in the previous step added the Microsoft test SDK, the NUnit test framework, and the NUnit test adapter. Now, add the `PrimeService` class library as another dependency to the project. Use the [`dotnet add reference`](../tools/dotnet-reference-add.md) command: @@ -151,9 +151,9 @@ namespace Prime.UnitTests.Services The `[TestFixture]` attribute denotes a class that contains unit tests. The `[Test]` attribute indicates a method is a test method. -Save this file and execute the [`dotnet test`](../tools/dotnet-test.md) command to build the tests and the class library and run the tests. The NUnit test runner contains the program entry point to run your tests. `dotnet test` starts the test runner using the unit test project you've created. +Save this file and execute the [`dotnet test`](../tools/dotnet-test.md) command to build the tests and the class library and run the tests. The NUnit test runner contains the program entry point to run your tests. `dotnet test` starts the test runner using the unit test project you created. -Your test fails. You haven't created the implementation yet. Make the test pass by writing the simplest code in the `PrimeService` class that works: +Your test fails. You didn't create the implementation yet. Make the test pass by writing the simplest code in the `PrimeService` class that works: ```csharp public bool IsPrime(int candidate) @@ -170,7 +170,7 @@ In the *unit-testing-using-nunit* directory, run `dotnet test` again. The `dotne ## Adding more features -Now that you've made one test pass, it's time to write more. There are a few other simple cases for prime numbers: 0, -1. You could add new tests with the `[Test]` attribute, but that quickly becomes tedious. There are other NUnit attributes that enable you to write a suite of similar tests. A `[TestCase]` attribute is used to create a suite of tests that execute the same code but have different input arguments. You can use the `[TestCase]` attribute to specify values for those inputs. +Now that you made one test pass, it's time to write more. There are a few other simple cases for prime numbers: 0, -1. You could add new tests with the `[Test]` attribute, but that quickly becomes tedious. There are other NUnit attributes that enable you to write a suite of similar tests. A `[TestCase]` attribute is used to create a suite of tests that execute the same code but have different input arguments. You can use the `[TestCase]` attribute to specify values for those inputs. Instead of creating new tests, apply this attribute to create a single data-driven test. The data driven test is a method that tests several values less than two, which is the lowest prime number: @@ -184,4 +184,4 @@ if (candidate < 2) Continue to iterate by adding more tests, theories, and code in the main library. You have the [finished version of the tests](https://github.com/dotnet/samples/blob/main/core/getting-started/unit-testing-using-nunit/PrimeService.Tests/PrimeService_IsPrimeShould.cs) and the [complete implementation of the library](https://github.com/dotnet/samples/blob/main/core/getting-started/unit-testing-using-nunit/PrimeService/PrimeService.cs). -You've built a small library and a set of unit tests for that library. You've also structured the solution so that adding new packages and tests is part of the standard workflow. You've concentrated most of your time and effort on solving the goals of the application. +You built a small library and a set of unit tests for that library. You've also structured the solution so that adding new packages and tests is part of the standard workflow. You've concentrated most of your time and effort on solving the goals of the application. diff --git a/docs/core/tools/telemetry.md b/docs/core/tools/telemetry.md index 04249a6b6de7b..55b143f1a9397 100644 --- a/docs/core/tools/telemetry.md +++ b/docs/core/tools/telemetry.md @@ -2,8 +2,7 @@ title: .NET SDK and .NET CLI telemetry description: The .NET SDK and the .NET CLI collect usage information and send it to Microsoft. Learn what data is collected and how to opt out. author: KathleenDollard -ms.date: 10/22/2025 -ai-usage: ai-assisted +ms.date: 10/07/2025 --- # .NET SDK and .NET CLI telemetry diff --git a/docs/core/versions/selection.md b/docs/core/versions/selection.md index 454e817865070..d364775f57281 100644 --- a/docs/core/versions/selection.md +++ b/docs/core/versions/selection.md @@ -32,7 +32,7 @@ SDK commands include `dotnet new` and `dotnet run`. The .NET CLI must choose an You can take advantage of the latest SDK features and improvements while targeting earlier .NET runtime versions. You can target different runtime versions of .NET using the same SDK tools. -In some circumstances, you may need to use a specific version of the SDK. You specify that version in a [*global.json* file](../tools/global-json.md). +In some circumstances, you might need to use a specific version of the SDK. You specify that version in a [*global.json* file](../tools/global-json.md). *global.json* can be placed anywhere in the file hierarchy. You control which projects a given *global.json* applies to by its place in the file system. The .NET CLI searches for a *global.json* file iteratively navigating the path upward from the current working directory (which isn't necessarily the same as the project directory). The first *global.json* file found specifies the version used. If that SDK version is installed, that version is used. If the SDK specified in the *global.json* isn't found, the .NET CLI uses [matching rules](../tools/global-json.md#matching-rules) to select a compatible SDK, or fails if none is found. @@ -56,7 +56,7 @@ For more information about SDK version selection, see the [Matching rules](../to ### Updating the SDK version -It is important to update to the latest version of the SDK regularly to adopt the latest features, performance improvements, and bug fixes. To easily check for updates to the SDK, use the `dotnet sdk check` [command](../tools/dotnet-sdk-check.md). Additionally, if you select a specific version using *global.json*, consider a tool such as Dependabot to automatically update the pinned SDK version as new versions become available. +It's important to update to the latest version of the SDK regularly to adopt the latest features, performance improvements, and bug fixes. To easily check for updates to the SDK, use the `dotnet sdk check` [command](../tools/dotnet-sdk-check.md). Additionally, if you select a specific version using *global.json*, consider a tool such as Dependabot to automatically update the pinned SDK version as new versions become available. ## Target framework monikers define build time APIs @@ -86,7 +86,7 @@ When you run an application from source with [`dotnet run`](../tools/dotnet-run. The host chooses the latest patch version installed on the machine. For example, if you specified `net5.0` in your project file, and `5.0.2` is the latest .NET runtime installed, the `5.0.2` runtime is used. -If no acceptable `5.0.*` version is found, a new `5.*` version is used. For example, if you specified `net5.0` and only `5.1.0` is installed, the application runs using the `5.1.0` runtime. This behavior is referred to as "minor version roll-forward." Lower versions also won't be considered. When no acceptable runtime is installed, the application won't run. +If no acceptable `5.0.*` version is found, a new `5.*` version is used. For example, if you specified `net5.0` and only `5.1.0` is installed, the application runs using the `5.1.0` runtime. This behavior is referred to as "minor version roll-forward." Lower versions also won't be considered. When no acceptable runtime is installed, the application doesn't run. A few usage examples demonstrate the behavior, if you target 5.0: @@ -95,11 +95,11 @@ A few usage examples demonstrate the behavior, if you target 5.0: - ✔️ 5.0 is specified. No 5.0.* versions are installed. 5.1.0 is the highest runtime version installed. 5.1.0 is used. - ❌ 3.0 is specified. No 3.x versions are installed. 5.0.0 is the highest runtime installed. An error message is displayed. -Minor version roll-forward has one side-effect that may affect end users. Consider the following scenario: +Minor version roll-forward has one side-effect that can affect end users. Consider the following scenario: 01. The application specifies that 5.0 is required. 02. When run, version 5.0.* isn't installed, however, 5.1.0 is. Version 5.1.0 is used. -03. Later, the user installs 5.0.3 and runs the application again, 5.0.3 will now be used. +03. Later, the user installs 5.0.3 and runs the application again, 5.0.3 is now used. It's possible that 5.0.3 and 5.1.0 behave differently, particularly for scenarios like serializing binary data. @@ -176,11 +176,11 @@ Then the resolved version is as follows in each case: You can publish an application as a [**self-contained distribution**](../deploying/index.md#self-contained-deployment). This approach bundles the .NET runtime and libraries with your application. Self-contained deployments don't have a dependency on runtime environments. Runtime version selection occurs at publishing time, not run time. -The *restore* event that occurs when publishing selects the latest patch version of the given runtime family. For example, `dotnet publish` will select .NET 5.0.3 if it's the latest patch version in the .NET 5 runtime family. The target framework (including the latest installed security patches) is packaged with the application. +The *restore* event that occurs when publishing selects the latest patch version of the given runtime family. For example, `dotnet publish` selects .NET 5.0.3 if it's the latest patch version in the .NET 5 runtime family. The target framework (including the latest installed security patches) is packaged with the application. An error occurs if the minimum version specified for an application isn't satisfied. `dotnet publish` binds to the latest runtime patch version (within a given major.minor version family). `dotnet publish` doesn't support the roll-forward semantics of `dotnet run`. For more information about patches and self-contained deployments, see the article on [runtime patch selection](../deploying/runtime-patch-selection.md) in deploying .NET applications. -Self-contained deployments may require a specific patch version. You can override the minimum runtime patch version (to higher or lower versions) in the project file, as shown in the following example: +Self-contained deployments might require a specific patch version. You can override the minimum runtime patch version (to higher or lower versions) in the project file, as shown in the following example: ``` xml diff --git a/docs/fundamentals/code-analysis/code-style-rule-options.md b/docs/fundamentals/code-analysis/code-style-rule-options.md index 36ba85bb3865b..c4a76c7533bb9 100644 --- a/docs/fundamentals/code-analysis/code-style-rule-options.md +++ b/docs/fundamentals/code-analysis/code-style-rule-options.md @@ -13,7 +13,7 @@ You can define and maintain consistent *code style* in your codebase by defining > [!TIP] > > - When you define code style options in an EditorConfig file, you're configuring how you want the [code style analyzers](overview.md#code-style-analysis) to analyze your code. The EditorConfig file is the configuration file for these analyzers. -> - Code style options can also be set in Visual Studio in the [Text editor options](/visualstudio/ide/code-styles-and-code-cleanup) dialog. These are per-user options that are only respected while editing in Visual Studio. These options aren't respected at build time or by other IDEs. Additionally, if the project or solution opened inside Visual Studio has an EditorConfig file, then options from the EditorConfig file take precedence. In Visual Studio on Windows, you can also generate an EditorConfig file from your text-editor options. Select **Tools** > **Options** > **Text Editor** > [**C#** or **Basic**] > **Code Style** > **General**, and then click **Generate .editorconfig file from settings**. For more information, see [Code style preferences](/visualstudio/ide/code-styles-and-code-cleanup). +> - Code style options can also be set in Visual Studio in the [Text editor options](/visualstudio/ide/code-styles-and-code-cleanup) dialog. These are per-user options that are only respected while editing in Visual Studio. These options aren't respected at build time or by other IDEs. Additionally, if the project or solution opened inside Visual Studio has an EditorConfig file, then options from the EditorConfig file take precedence. In Visual Studio on Windows, you can also generate an EditorConfig file from your text-editor options. Select **Tools** > **Options** > **Text Editor** > [**C#** or **Basic**] > **Code Style** > **General**, and then select **Generate .editorconfig file from settings**. For more information, see [Code style preferences](/visualstudio/ide/code-styles-and-code-cleanup). Code style rules are divided into following subcategories: diff --git a/docs/fundamentals/networking/sockets/socket-services.md b/docs/fundamentals/networking/sockets/socket-services.md index 0681ff39900d5..939b88b719b80 100644 --- a/docs/fundamentals/networking/sockets/socket-services.md +++ b/docs/fundamentals/networking/sockets/socket-services.md @@ -21,7 +21,7 @@ ai-usage: ai-assisted # Use Sockets to send and receive data over TCP -Before you can use a socket to communicate with remote devices, the socket must be initialized with protocol and network address information. The constructor for the class has parameters that specify the address family, socket type, and protocol type that the socket uses to make connections. When connecting a client socket to a server socket, the client will use an `IPEndPoint` object to specify the network address of the server. +Before you can use a socket to communicate with remote devices, the socket must be initialized with protocol and network address information. The constructor for the class has parameters that specify the address family, socket type, and protocol type that the socket uses to make connections. When connecting a client socket to a server socket, the client uses an `IPEndPoint` object to specify the network address of the server. [!INCLUDE [ip-endpoint](../includes/ip-endpoint.md)] @@ -40,7 +40,7 @@ The preceding C# code: - Encodes and sends a message to the server using . - Writes the sent message to the console. - Initializes a buffer to receive data from the server using . - - When the `response` is an acknowledgment, it is written to the console and the loop is exited. + - When the `response` is an acknowledgment, it's written to the console and the loop is exited. - Finally, the `client` socket calls given , which shuts down both send and receive operations. @@ -75,7 +75,7 @@ Socket server sent acknowledgment: "<|ACK|>" Press ENTER to continue... ``` -The client application will send a message to the server, and the server will respond with an acknowledgment. +The client application sends a message to the server, and the server will respond with an acknowledgment. ```dotnetcli dotnet run --project socket-client diff --git a/docs/standard/assembly/index.md b/docs/standard/assembly/index.md index 70b41d7ac8185..973adb6daea9d 100644 --- a/docs/standard/assembly/index.md +++ b/docs/standard/assembly/index.md @@ -27,7 +27,7 @@ Assemblies have the following properties: - Assemblies are implemented as *.exe* or *.dll* files. -- For libraries that target .NET Framework, you can share assemblies between applications by putting them in the [global assembly cache (GAC)](../../framework/app-domains/gac.md). Strong-name assemblies before you can include them in the GAC. For more information, see [Strong-named assemblies](strong-named.md). +- For libraries that target .NET Framework, you can share assemblies between applications by putting them in the [global assembly cache (GAC)](../../framework/app-domains/gac.md). You must strong-name assemblies before you can include them in the GAC. For more information, see [Strong-named assemblies](strong-named.md). - Assemblies are only loaded into memory if they're required. If they aren't used, they aren't loaded. Therefore, assemblies can be an efficient way to manage resources in larger projects. diff --git a/docs/standard/base-types/formatting-types.md b/docs/standard/base-types/formatting-types.md index 29c7f40b64b74..270966bb303e8 100644 --- a/docs/standard/base-types/formatting-types.md +++ b/docs/standard/base-types/formatting-types.md @@ -33,9 +33,9 @@ Formatting is the process of converting an instance of a class or structure, or > [!NOTE] > Parsing is the inverse of formatting. A parsing operation creates an instance of a data type from its string representation. For more information, see [Parsing Strings](parsing-strings.md). For information about serialization and deserialization, see [Serialization in .NET](../serialization/index.md). -The basic mechanism for formatting is the default implementation of the method, which is discussed in the [Default Formatting Using the ToString Method](#default-formatting-using-the-tostring-method) section later in this topic. However, .NET provides several ways to modify and extend its default formatting support. These include the following: +The basic mechanism for formatting is the default implementation of the method, which is discussed in the [Default Formatting Using the ToString Method](#default-formatting-using-the-tostring-method) section later in this article. However, .NET provides several ways to modify and extend its default formatting support. These include the following: -- Overriding the method to define a custom string representation of an object's value. For more information, see the [Override the ToString Method](#override-the-tostring-method) section later in this topic. +- Overriding the method to define a custom string representation of an object's value. For more information, see the [Override the ToString Method](#override-the-tostring-method) section later in this article. - Defining format specifiers that enable the string representation of an object's value to take multiple forms. For example, the "X" format specifier in the following statement converts an integer to the string representation of a hexadecimal value. @@ -63,7 +63,7 @@ The following sections examine these methods for converting an object to its str ## Default formatting using the ToString method -Every type that is derived from automatically inherits a parameterless `ToString` method, which returns the name of the type by default. The following example illustrates the default `ToString` method. It defines a class named `Automobile` that has no implementation. When the class is instantiated and its `ToString` method is called, it displays its type name. Note that the `ToString` method isn't explicitly called in the example. The method implicitly calls the `ToString` method of the object passed to it as an argument. +Every type that is derived from automatically inherits a parameterless `ToString` method, which returns the name of the type by default. The following example illustrates the default `ToString` method. It defines a class named `Automobile` that has no implementation. When the class is instantiated and its `ToString` method is called, it displays its type name. The `ToString` method isn't explicitly called in the example. The method implicitly calls the `ToString` method of the object passed to it as an argument. [!code-csharp[Conceptual.Formatting.Overview#1](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/default1.cs#1)] [!code-vb[Conceptual.Formatting.Overview#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/default1.vb#1)] @@ -83,7 +83,7 @@ Displaying the name of a type is often of limited use and doesn't allow consumer [!code-csharp[Conceptual.Formatting.Overview#2](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/overrides1.cs#2)] [!code-vb[Conceptual.Formatting.Overview#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/overrides1.vb#2)] -In .NET, the `ToString` method of each primitive value type has been overridden to display the object's value instead of its name. The following table shows the override for each primitive type. Note that most of the overridden methods call another overload of the `ToString` method and pass it the "G" format specifier, which defines the general format for its type, and an object that represents the current culture. +In .NET, the `ToString` method of each primitive value type has been overridden to display the object's value instead of its name. The following table shows the override for each primitive type. Most of the overridden methods call another overload of the `ToString` method and pass it the "G" format specifier, which defines the general format for its type, and an object that represents the current culture. |Type|ToString override| |----------|-----------------------| @@ -112,7 +112,7 @@ All numeric types, date and time types, and enumeration types in .NET support a ### Standard format strings -A standard format string contains a single format specifier, which is an alphabetic character that defines the string representation of the object to which it is applied, along with an optional precision specifier that affects how many digits are displayed in the result string. If the precision specifier is omitted or isn't supported, a standard format specifier is equivalent to a standard format string. +A standard format string contains a single format specifier, which is an alphabetic character that defines the string representation of the object to which it's applied, along with an optional precision specifier that affects how many digits are displayed in the result string. If the precision specifier is omitted or isn't supported, a standard format specifier is equivalent to a standard format string. .NET defines a set of standard format specifiers for all numeric types, all date and time types, and all enumeration types. For example, each of these categories supports a "G" standard format specifier, which defines a general string representation of a value of that type. @@ -145,7 +145,7 @@ Standard format strings for numeric types usually define a result string whose p - The property, which determines the negative sign used in the result string if parentheses aren't used to indicate negative values. -In addition, numeric format strings may include a precision specifier. The meaning of this specifier depends on the format string with which it is used, but it typically indicates either the total number of digits or the number of fractional digits that should appear in the result string. For example, the following example uses the "X4" standard numeric string and a precision specifier to create a string value that has four hexadecimal digits. +In addition, numeric format strings can include a precision specifier. The meaning of this specifier depends on the format string with which it's used, but it typically indicates either the total number of digits or the number of fractional digits that should appear in the result string. For example, the following example uses the "X4" standard numeric string and a precision specifier to create a string value that has four hexadecimal digits. [!code-csharp[Conceptual.Formatting.Overview#6](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/precisionspecifier1.cs#6)] [!code-vb[Conceptual.Formatting.Overview#6](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/precisionspecifier1.vb#6)] @@ -159,11 +159,11 @@ Standard format strings for date and time values are aliases for custom format s For more information about standard date and time format strings, see [Standard Date and Time Format Strings](standard-date-and-time-format-strings.md). -You can also use standard format strings to define the string representation of an application-defined object that is produced by the object's `ToString(String)` method. You can define the specific standard format specifiers that your object supports, and you can determine whether they are case-sensitive or case-insensitive. Your implementation of the `ToString(String)` method should support the following: +You can also use standard format strings to define the string representation of an application-defined object that is produced by the object's `ToString(String)` method. You can define the specific standard format specifiers that your object supports, and you can determine whether they're case-sensitive or case-insensitive. Your implementation of the `ToString(String)` method should support the following: - A "G" format specifier that represents a customary or common format of the object. The parameterless overload of your object's `ToString` method should call its `ToString(String)` overload and pass it the "G" standard format string. -- Support for a format specifier that is equal to a null reference (`Nothing` in Visual Basic). A format specifier that is equal to a null reference should be considered equivalent to the "G" format specifier. +- Support for a format specifier that's equal to a null reference (`Nothing` in Visual Basic). A format specifier that's equal to a null reference should be considered equivalent to the "G" format specifier. For example, a `Temperature` class can internally store the temperature in degrees Celsius and use format specifiers to represent the value of the `Temperature` object in degrees Celsius, degrees Fahrenheit, and kelvins. The following example provides an illustration. @@ -189,11 +189,11 @@ The following example defines a custom format string that displays an , , , , , , , , , , , and types), as well as the , , , , and all enumeration types, support formatting with format strings. For information on the specific format strings supported by each type, see the following topics: +All numeric types (that is, the , , , , , , , , , , , and types), as well as the , , , , and all enumeration types, support formatting with format strings. For information on the specific format strings supported by each type, see the following articles: |Title|Definition| |-----------|----------------| @@ -208,7 +208,7 @@ All numeric types (that is, the , , interface, which is provided as a parameter to one or more overloads of the `ToString` method of numeric types and date and time types. implementations are used in .NET to support culture-specific formatting. The following example illustrates how the string representation of an object changes when it is formatted with three objects that represent different cultures. +Although format specifiers let you customize the formatting of objects, producing a meaningful string representation of objects often requires additional formatting information. For example, formatting a number as a currency value by using either the "C" standard format string or a custom format string such as "$ #,#.00" requires, at a minimum, information about the correct currency symbol, group separator, and decimal separator to be available to include in the formatted string. In .NET, this extra formatting information is made available through the interface, which is provided as a parameter to one or more overloads of the `ToString` method of numeric types and date and time types. implementations are used in .NET to support culture-specific formatting. The following example illustrates how the string representation of an object changes when it's formatted with three objects that represent different cultures. [!code-csharp[Conceptual.Formatting.Overview#11](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/iformatprovider1.cs#11)] [!code-vb[Conceptual.Formatting.Overview#11](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/iformatprovider1.vb#11)] @@ -217,7 +217,7 @@ The interface includes one method, is a callback method. When you call a `ToString` method overload that includes an parameter, it calls the method of that object. The method is responsible for returning an object that provides the necessary formatting information, as specified by its `formatType` parameter, to the `ToString` method. -A number of formatting or string conversion methods include a parameter of type , but in many cases the value of the parameter is ignored when the method is called. The following table lists some of the formatting methods that use the parameter and the type of the object that they pass to the method. +Many formatting or string conversion methods include a parameter of type , but in many cases the value of the parameter is ignored when the method is called. The following table lists some of the formatting methods that use the parameter and the type of the object that they pass to the method. |Method|Type of `formatType` parameter| |------------|------------------------------------| @@ -306,7 +306,7 @@ In addition to replacing a format item with the string representation of its cor - The specific way in which an object is represented as a string, if the object implements the interface and supports format strings. You do this by following the format item's index with a `:` (colon) followed by a valid format string. The previous example did this by formatting a date value with the "d" (short date pattern) format string (for example, `{0:d}`) and by formatting a numeric value with the "C2" format string (for example, `{2:C2}`) to represent the number as a currency value with two fractional decimal digits. -- The width of the field that contains the object's string representation, and the alignment of the string representation in that field. You do this by following the format item's index with a `,` (comma) followed the field width. The string is right-aligned in the field if the field width is a positive value, and it is left-aligned if the field width is a negative value. The following example left-aligns date values in a 20-character field, and it right-aligns decimal values with one fractional digit in an 11-character field. +- The width of the field that contains the object's string representation, and the alignment of the string representation in that field. You do this by following the format item's index with a `,` (comma) followed the field width. The string is right-aligned in the field if the field width is a positive value, and it's left-aligned if the field width is a negative value. The following example left-aligns date values in a 20-character field, and it right-aligns decimal values with one fractional digit in an 11-character field. [!code-csharp[Conceptual.Formatting.Overview#22](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/composite2.cs#22)] [!code-vb[Conceptual.Formatting.Overview#22](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/composite2.vb#22)] @@ -326,7 +326,7 @@ The following example provides an implementation [!code-csharp[Conceptual.Formatting.Overview#15](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/icustomformatter1.cs#15)] [!code-vb[Conceptual.Formatting.Overview#15](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/icustomformatter1.vb#15)] -The following example uses the `ByteByByteFormatter` class to format integer values. Note that the method is called more than once in the second method call, and that the default provider is used in the third method call because the .`ByteByByteFormatter.Format` method doesn't recognize the "N0" format string and returns a null reference (`Nothing` in Visual Basic). +The following example uses the `ByteByByteFormatter` class to format integer values. The method is called more than once in the second method call, and that the default provider is used in the third method call because the .`ByteByByteFormatter.Format` method doesn't recognize the "N0" format string and returns a null reference (`Nothing` in Visual Basic). [!code-csharp[Conceptual.Formatting.Overview#16](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.formatting.overview/cs/icustomformatter1.cs#16)] [!code-vb[Conceptual.Formatting.Overview#16](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.formatting.overview/vb/icustomformatter1.vb#16)] diff --git a/docs/standard/base-types/regular-expressions.md b/docs/standard/base-types/regular-expressions.md index 659b176034d24..cd73ec72f38d1 100644 --- a/docs/standard/base-types/regular-expressions.md +++ b/docs/standard/base-types/regular-expressions.md @@ -42,7 +42,7 @@ For many applications that deal with strings or that parse large blocks of text, - The regular expression pattern to identify in the text. - In .NET, regular expression patterns are defined by a special syntax or language, which is compatible with Perl 5 regular expressions and adds some additional features such as right-to-left matching. For more information, see [Regular Expression Language - Quick Reference](regular-expression-language-quick-reference.md). + In .NET, regular expression patterns are defined by a special syntax or language, which is compatible with Perl 5 regular expressions and adds some other features such as right-to-left matching. For more information, see [Regular Expression Language - Quick Reference](regular-expression-language-quick-reference.md). - The text to parse for the regular expression pattern. @@ -68,7 +68,7 @@ The class includes string search and replacement methods th [!INCLUDE [regex](../../../includes/regex.md)] > [!TIP] -> The namespace contains a number of regular expression objects that implement predefined regular expression patterns for parsing strings from HTML, XML, and ASP.NET documents. For example, the class identifies start tags in a string, and the class identifies ASP.NET comments in a string. +> The namespace contains many regular expression objects that implement predefined regular expression patterns for parsing strings from HTML, XML, and ASP.NET documents. For example, the class identifies start tags in a string, and the class identifies ASP.NET comments in a string. ### Example 1: Replace substrings diff --git a/docs/standard/clr.md b/docs/standard/clr.md index a06ab205d7eac..0366187e77dfb 100644 --- a/docs/standard/clr.md +++ b/docs/standard/clr.md @@ -60,7 +60,7 @@ Language compilers and tools expose the runtime's functionality in ways that are .NET Core and .NET 5+ releases have a single product version, that is, there's no separate CLR version. For a list of .NET Core versions, see [Download .NET Core](https://dotnet.microsoft.com/download/dotnet). -However, .NET Framework version number doesn't necessarily correspond to the version number of the CLR it includes. For a list of .NET Framework versions and their corresponding CLR versions, see [.NET Framework versions and dependencies](../framework/install/versions-and-dependencies.md). +However, the .NET Framework version number doesn't necessarily correspond to the version number of the CLR it includes. For a list of .NET Framework versions and their corresponding CLR versions, see [.NET Framework versions and dependencies](../framework/install/versions-and-dependencies.md). ## Related articles diff --git a/docs/standard/exceptions/best-practices-for-exceptions.md b/docs/standard/exceptions/best-practices-for-exceptions.md index 630c1eadc0f35..694fb2e295c85 100644 --- a/docs/standard/exceptions/best-practices-for-exceptions.md +++ b/docs/standard/exceptions/best-practices-for-exceptions.md @@ -35,7 +35,7 @@ Clean up resources that are allocated with either `using` statements or `finally ### Handle common conditions to avoid exceptions -For conditions that are likely to occur but might trigger an exception, consider handling them in a way that avoids the exception. For example, if you try to close a connection that's already closed, you'll get an `InvalidOperationException`. You can avoid that by using an `if` statement to check the connection state before trying to close it. +For conditions that are likely to occur but might trigger an exception, consider handling them in a way that avoids the exception. For example, if you try to close a connection that's already closed, you get an `InvalidOperationException`. You can avoid that by using an `if` statement to check the connection state before trying to close it. [!code-csharp[Conceptual.Exception.Handling#2](./snippets/best-practices/csharp/source.cs#2)] [!code-vb[Conceptual.Exception.Handling#2](~/samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.exception.handling/vb/source.vb#2)] @@ -178,7 +178,7 @@ catch (FileNotFoundException e) Console.WriteLine("I was here."); -if (edi isn't null) +if (edi is not null) edi.Throw(); ``` @@ -220,7 +220,7 @@ Introduce a new exception class only when a predefined one doesn't apply. For ex - If invalid parameters are passed, throw an exception or one of the predefined classes that derive from . > [!NOTE] -> While it's best to use predefined exception types when possible, you shouldn't raise some *reserved* exception types, such as , , and . For more information, see [CA2201: Do not raise reserved exception types](../../fundamentals/code-analysis/quality-rules/ca2201.md). +> While it's best to use predefined exception types when possible, you shouldn't raise some *reserved* exception types, such as , , and . For more information, see [CA2201: Don't raise reserved exception types](../../fundamentals/code-analysis/quality-rules/ca2201.md). ### Use exception builder methods @@ -286,7 +286,7 @@ The following best practices concern custom exception types: - [End exception class names with `Exception`](#end-exception-class-names-with-exception) - [Include three constructors](#include-three-constructors) -- [Provide additional properties as needed](#provide-additional-properties-as-needed) +- [Provide more properties as needed](#provide-additional-properties-as-needed) ### End exception class names with `Exception` @@ -305,9 +305,9 @@ Use at least the three common constructors when creating your own exception clas For an example, see [How to: Create user-defined exceptions](how-to-create-user-defined-exceptions.md). -### Provide additional properties as needed +### Provide more properties as needed -Provide additional properties for an exception (in addition to the custom message string) only when there's a programmatic scenario where the additional information is useful. For example, the provides the property. +Provide more properties for an exception (in addition to the custom message string) only when there's a programmatic scenario where the additional information is useful. For example, the provides the property. ### See also From e5c7c2e68a8d29db0e3311d3833453d6732ce44c Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Thu, 23 Oct 2025 09:20:13 -0700 Subject: [PATCH 17/30] fix invalid link --- docs/standard/exceptions/best-practices-for-exceptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/exceptions/best-practices-for-exceptions.md b/docs/standard/exceptions/best-practices-for-exceptions.md index 694fb2e295c85..19de71b2c8890 100644 --- a/docs/standard/exceptions/best-practices-for-exceptions.md +++ b/docs/standard/exceptions/best-practices-for-exceptions.md @@ -286,7 +286,7 @@ The following best practices concern custom exception types: - [End exception class names with `Exception`](#end-exception-class-names-with-exception) - [Include three constructors](#include-three-constructors) -- [Provide more properties as needed](#provide-additional-properties-as-needed) +- [Provide more properties as needed](#provide-more-properties-as-needed) ### End exception class names with `Exception` From 46b92f7c110b66804fe0796c586ea53c1ac81ca5 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Thu, 23 Oct 2025 10:02:53 -0700 Subject: [PATCH 18/30] Update docs/core/extensions/logging.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/core/extensions/logging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index 05a1aaa46a67b..9ad11d5267c6a 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -437,7 +437,7 @@ Parameter values: param1, param2 ``` > [!NOTE] -> Be mindful when using multiple placeholders within a single message template, as they're ordinal-based. The names aren't_ used to align the arguments to the placeholders. +> Be mindful when using multiple placeholders within a single message template, as they're ordinal-based. The names aren't used to align the arguments to the placeholders. This approach lets logging providers implement [semantic or structured logging](https://github.com/NLog/NLog/wiki/How-to-use-structured-logging). The arguments themselves are passed to the logging system, not just the formatted message template. This enables logging providers to store the parameter values as fields. Consider this logger method: From f78528798bc0715dc3c81b48887b3969d020ec98 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Thu, 23 Oct 2025 10:03:08 -0700 Subject: [PATCH 19/30] Update docs/core/extensions/logging-providers.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/core/extensions/logging-providers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/extensions/logging-providers.md b/docs/core/extensions/logging-providers.md index 0fc853e002dc3..acc992a630f96 100644 --- a/docs/core/extensions/logging-providers.md +++ b/docs/core/extensions/logging-providers.md @@ -197,7 +197,7 @@ For more information, see the following resources: If you plan to develop your own implementation of the interface and corresponding custom implementation of , consider the following points: - The method is synchronous. -- The lifetime of log state and objects shouldn't* be assumed. +- The lifetime of log state and objects shouldn't be assumed. An implementation of `ILoggerProvider` creates an `ILogger` via its method. If your implementation strives to queue logging messages in a non-blocking manner, the messages should first be materialized or the object state that's used to materialize a log entry should be serialized. Doing so avoids potential exceptions from disposed objects. From eac076ec4c09a3a126739a4b3b622adbd5c9319f Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 10:16:32 -0700 Subject: [PATCH 20/30] Update docs/core/deploying/native-aot/index.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/deploying/native-aot/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/deploying/native-aot/index.md b/docs/core/deploying/native-aot/index.md index 5f578e3fa7d0d..bb07bd14be2d8 100644 --- a/docs/core/deploying/native-aot/index.md +++ b/docs/core/deploying/native-aot/index.md @@ -135,7 +135,7 @@ Native AOT apps have the following limitations: - Implies compilation into a single file, which has known [incompatibilities](../single-file/overview.md#api-incompatibility). - Apps include required runtime libraries (just like [self-contained apps](../index.md#self-contained-deployment), increasing their size as compared to framework-dependent apps). - always use their interpreted form, which is slower than run-time generated compiled code. -- Generic parameters substituted with struct type arguments has specialized code generated for each instantiation. In the dynamic runtime, many instantiations are generated on-demand. In Native AOT, all instantiations are pre-generated. This can have significant impact to the disk size of the application. Generic virtual methods and generic instance methods will also have an instantiation for every implementing or overriding type. +- Generic parameters substituted with struct type arguments have specialized code generated for each instantiation. In the dynamic runtime, many instantiations are generated on-demand. In Native AOT, all instantiations are pre-generated. This can have significant impact to the disk size of the application. Generic virtual methods and generic instance methods will also have an instantiation for every implementing or overriding type. - Not all the runtime libraries are fully annotated to be Native AOT compatible. That is, some warnings in the runtime libraries aren't actionable by end developers. - [Diagnostic support for debugging and profiling](./diagnostics.md) with some limitations. - Support for some ASP.NET Core features. For more information, see [ASP.NET Core support for Native AOT](/aspnet/core/fundamentals/native-aot/). From 966cd42b4a95a72e22ff150cb7dcad3f03c9b6f7 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 10:17:31 -0700 Subject: [PATCH 21/30] Update docs/core/deploying/single-file/overview.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/deploying/single-file/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/deploying/single-file/overview.md b/docs/core/deploying/single-file/overview.md index 2a432d4364386..a8f77464478c5 100644 --- a/docs/core/deploying/single-file/overview.md +++ b/docs/core/deploying/single-file/overview.md @@ -211,7 +211,7 @@ We have some recommendations for fixing common scenarios: Some workflows require post-processing of binaries before bundling. A common example is signing. The dotnet SDK provides MSBuild extension points to allow processing binaries just before single-file bundling. The available APIs are: - A target `PrepareForBundle` that is called before `GenerateSingleFileBundle` -- An `` containing all files that is bundled +- An `` containing all files that are to be bundled - A Property `AppHostFile` that will specify the apphost template. Post-processing might want to exclude the apphost from processing. To plug into this involves creating a target that is executed between `PrepareForBundle` and `GenerateSingleFileBundle`. From 39221d8be2cbaeb65c3f8d6e310ebd913a7be2a0 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 10:17:51 -0700 Subject: [PATCH 22/30] Update docs/core/extensions/caching.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/extensions/caching.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/extensions/caching.md b/docs/core/extensions/caching.md index bbaba0ef30415..cac0a679cff7d 100644 --- a/docs/core/extensions/caching.md +++ b/docs/core/extensions/caching.md @@ -262,7 +262,7 @@ Consider any of the available implementations of the `IDistributedCache` from th ### Distributed caching API -The distributed caching APIs are a bit more primitive than their in-memory caching API counterparts. The key-value pairs are a bit more basic. In-memory caching keys are based on an `object`, whereas the distributed keys are a `string`. With in-memory caching, the value can be any strongly-typed generic, whereas values in distributed caching are persisted as `byte[]`. That's not to say that various implementations don't expose strongly-typed generic values but that is an implementation detail. +The distributed caching APIs are a bit more primitive than their in-memory caching API counterparts. The key-value pairs are a bit more basic. In-memory caching keys are based on an `object`, whereas the distributed keys are a `string`. With in-memory caching, the value can be any strongly typed generic, whereas values in distributed caching are persisted as `byte[]`. That's not to say that various implementations don't expose strongly typed generic values, but that's an implementation detail. #### Create values From 502339ede1cf6372d6d35255ca35cd74d3c0c1f6 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 10:18:11 -0700 Subject: [PATCH 23/30] Update docs/standard/parallel-programming/task-based-asynchronous-programming.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- .../parallel-programming/task-based-asynchronous-programming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/parallel-programming/task-based-asynchronous-programming.md b/docs/standard/parallel-programming/task-based-asynchronous-programming.md index bc3502d6ebf05..3990cc4288922 100644 --- a/docs/standard/parallel-programming/task-based-asynchronous-programming.md +++ b/docs/standard/parallel-programming/task-based-asynchronous-programming.md @@ -239,7 +239,7 @@ The class provides static methods that - To encapsulate Asynchronous Programming Model `BeginX` and `EndX` methods in a or instance, use the methods. For more information, see [TPL and Traditional .NET Framework Asynchronous Programming](tpl-and-traditional-async-programming.md). -The default can be accessed as a static property on the class or class. You can also instantiate a directly and specify various options that include a , a option, a option, or a . Whatever options are specified when you create the task factory is applied to all tasks that it creates unless the is created by using the enumeration, in which case the task's options override those of the task factory. +The default can be accessed as a static property on the class or class. You can also instantiate a directly and specify various options that include a , a option, a option, or a . Whatever options are specified when you create the task factory are applied to all tasks that it creates unless the is created by using the enumeration, in which case the task's options override those of the task factory. ## Tasks without delegates From 31480f6f9939ca4cbcad1f71acc41a400faffb37 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 10:21:08 -0700 Subject: [PATCH 24/30] Update docs/standard/garbage-collection/fundamentals.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/standard/garbage-collection/fundamentals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/garbage-collection/fundamentals.md b/docs/standard/garbage-collection/fundamentals.md index 09f4f7dbc5a5a..0a88a4c70a160 100644 --- a/docs/standard/garbage-collection/fundamentals.md +++ b/docs/standard/garbage-collection/fundamentals.md @@ -172,7 +172,7 @@ A garbage collection has the following phases: - A marking phase that finds and creates a list of all live objects. -- A relocating phase that updates the references to the objects that is compacted. +- A relocating phase that updates the references to the objects that are compacted. - A compacting phase that reclaims the space occupied by the dead objects and compacts the surviving objects. The compacting phase moves objects that have survived a garbage collection towards the older end of the segment. From 6a1d702bf69af3bcf70c7009a4934e01f2ba5d5a Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Mon, 27 Oct 2025 11:12:46 -0700 Subject: [PATCH 25/30] address review feedback --- docs/core/extensions/dependency-injection.md | 18 +++++++++--------- docs/core/extensions/logging-providers.md | 4 ++-- docs/core/extensions/logging.md | 14 +++++++------- docs/core/tutorials/index.md | 3 +-- docs/standard/assembly/index.md | 2 +- docs/standard/clr.md | 2 +- docs/standard/commandline/index.md | 4 ++-- .../garbage-collection/fundamentals.md | 4 ++-- .../standard/io/how-to-write-text-to-a-file.md | 10 +++++----- .../system-text-json/converters-how-to.md | 2 +- 10 files changed, 31 insertions(+), 32 deletions(-) diff --git a/docs/core/extensions/dependency-injection.md b/docs/core/extensions/dependency-injection.md index 228ce453a313e..af6a135146094 100644 --- a/docs/core/extensions/dependency-injection.md +++ b/docs/core/extensions/dependency-injection.md @@ -12,7 +12,7 @@ ai-usage: ai-assisted .NET supports the dependency injection (DI) software design pattern, which is a technique for achieving [Inversion of Control (IoC)](../../architecture/modern-web-apps-azure/architectural-principles.md#dependency-inversion) between classes and their dependencies. Dependency injection in .NET is a built-in part of the framework, along with configuration, logging, and the options pattern. -A *dependency* is an object that another object depends on. Examine this `MessageWriter` class with a `Write` method that other classes depend on: +A *dependency* is an object that another object depends on. Examine the following `MessageWriter` class with a `Write` method that other classes depend on: ```csharp public class MessageWriter @@ -24,7 +24,7 @@ public class MessageWriter } ``` -A class can create an instance of the `MessageWriter` class to use its `Write` method. In this example, the `MessageWriter` class is a dependency of the `Worker` class: +A class can create an instance of the `MessageWriter` class to use its `Write` method. In the following example, the `MessageWriter` class is a dependency of the `Worker` class: ```csharp public class Worker : BackgroundService @@ -42,13 +42,13 @@ public class Worker : BackgroundService } ``` -The class creates and directly depends on the `MessageWriter` class. Hard-coded dependencies, such as in the previous example, are problematic and should be avoided for these reasons: +The class creates and directly depends on the `MessageWriter` class. Hard-coded dependencies, such as in the previous example, are problematic and should be avoided for the following reasons: - To replace `MessageWriter` with a different implementation, you must modify the `Worker` class. - If `MessageWriter` has dependencies, the `Worker` class must also configure them. In a large project with multiple classes depending on `MessageWriter`, the configuration code becomes scattered across the app. - This implementation is difficult to unit test. The app should use a mock or stub `MessageWriter` class, which isn't possible with this approach. -Dependency injection addresses these problems through: +Dependency injection addresses the following problems through: - The use of an interface or base class to abstract the dependency implementation. - Registration of the dependency in a service container. .NET provides a built-in service container, . Services are typically registered at the app's start-up and appended to an . Once all services are added, use to create the service container. @@ -150,9 +150,9 @@ public class ExampleService } ``` -In the preceding code, assume that logging is added and is resolvable from the service provider but the `FooService` and `BarService` types aren't. The constructor with the `ILogger` parameter resolves the `ExampleService` instance. Even though there's a constructor that defines more parameters, the `FooService` and `BarService` types aren't DI-resolvable. +In the preceding code, assume that logging has been added and is resolvable from the service provider but the `FooService` and `BarService` types aren't. The constructor with the `ILogger` parameter resolves the `ExampleService` instance. Even though there's a constructor that defines more parameters, the `FooService` and `BarService` types aren't DI-resolvable. -If there's ambiguity when discovering constructors, an exception is thrown. Consider this C# example service: +If there's ambiguity when discovering constructors, an exception is thrown. Consider the following C# example service: ```csharp public class ExampleService @@ -325,7 +325,7 @@ services.AddSingleton(); services.TryAddSingleton(); ``` -The `TryAddSingleton` has no effect, as it was already added and the "try" fails. The `ExampleService` asserts this: +The `TryAddSingleton` has no effect, as it was already added and the "try" fails. The `ExampleService` asserts the following: ```csharp public class ExampleService @@ -349,7 +349,7 @@ For more information, see: The [TryAddEnumerable(ServiceDescriptor)](xref:Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddEnumerable%2A) methods register the service only if there isn't already an implementation *of the same type*. Multiple services are resolved via `IEnumerable<{SERVICE}>`. When registering services, add an instance if one of the same types wasn't already added. Library authors use `TryAddEnumerable` to avoid registering multiple copies of an implementation in the container. -In this example, the first call to `TryAddEnumerable` registers `MessageWriter` as an implementation for `IMessageWriter1`. The second call registers `MessageWriter` for `IMessageWriter2`. The third call has no effect because `IMessageWriter1` already has a registered implementation of `MessageWriter`: +In the following example, the first call to `TryAddEnumerable` registers `MessageWriter` as an implementation for `IMessageWriter1`. The second call registers `MessageWriter` for `IMessageWriter2`. The third call has no effect because `IMessageWriter1` already has a registered implementation of `MessageWriter`: ```csharp public interface IMessageWriter1 { } @@ -366,7 +366,7 @@ services.TryAddEnumerable(ServiceDescriptor.Singleton objects. This example shows how to register a service by creating and adding a `ServiceDescriptor`: +`IServiceCollection` is a collection of objects. The following example shows how to register a service by creating and adding a `ServiceDescriptor`: ```csharp string secretKey = Configuration["SecretKey"]; diff --git a/docs/core/extensions/logging-providers.md b/docs/core/extensions/logging-providers.md index acc992a630f96..3ad3a73429c85 100644 --- a/docs/core/extensions/logging-providers.md +++ b/docs/core/extensions/logging-providers.md @@ -66,7 +66,7 @@ Microsoft Extensions include the following logging providers as part of the runt - [EventSource](#event-source) - [EventLog](#windows-eventlog) -The following logging providers are shipped by Microsoft, but not as part of the runtime libraries. They must be installed like NuGet packages. +The following logging providers are shipped by Microsoft, but not as part of the runtime libraries. They must be installed from NuGet packages. - [AzureAppServicesFile and AzureAppServicesBlob](#azure-app-service) - [ApplicationInsights](#azure-application-insights) @@ -83,7 +83,7 @@ The `Debug` provider writes log output by using the provider data using a . diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index 9ad11d5267c6a..c1f6119e35793 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -13,7 +13,7 @@ ai-usage: ai-assisted ## Get started -This first example shows the basics, but it's only suitable for a trivial console app. This sample console app relies on these NuGet packages: +This first example shows the basics, but it's only suitable for a trivial console app. This sample console app relies on the following NuGet packages: - [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) - [Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) @@ -276,7 +276,7 @@ The following algorithm is used for each provider when an `ILogger` is created f ## Log category -When an `ILogger` object is created, a *category* is specified. That category is included with each log message created by that instance of `ILogger`. The category string is arbitrary, but the convention is to use the fully qualified class name. For example, in an application with a service defined like this object, the category might be `"Example.DefaultService"`: +When an `ILogger` object is created, a *category* is specified. That category is included with each log message created by that instance of `ILogger`. The category string is arbitrary, but the convention is to use the fully qualified class name. For example, in an application with a service defined like the following object, the category might be `"Example.DefaultService"`: ```csharp namespace Example @@ -439,7 +439,7 @@ Parameter values: param1, param2 > [!NOTE] > Be mindful when using multiple placeholders within a single message template, as they're ordinal-based. The names aren't used to align the arguments to the placeholders. -This approach lets logging providers implement [semantic or structured logging](https://github.com/NLog/NLog/wiki/How-to-use-structured-logging). The arguments themselves are passed to the logging system, not just the formatted message template. This enables logging providers to store the parameter values as fields. Consider this logger method: +This approach lets logging providers implement [semantic or structured logging](https://github.com/NLog/NLog/wiki/How-to-use-structured-logging). The arguments themselves are passed to the logging system, not just the formatted message template. This enables logging providers to store the parameter values as fields. Consider the following logger method: ```csharp _logger.LogInformation("Getting item {Id} at {RunTime}", id, DateTime.Now); @@ -452,7 +452,7 @@ For example, when logging to Azure Table Storage: ### Log message template formatting -Log message templates support placeholder formatting. Templates can specify [any valid format](../../standard/base-types/formatting-types.md) for the given type argument. For example, consider this `Information` logger message template: +Log message templates support placeholder formatting. Templates can specify [any valid format](../../standard/base-types/formatting-types.md) for the given type argument. For example, consider the following `Information` logger message template: ```csharp _logger.LogInformation("Logged on {PlaceHolderName:MMMM dd, yyyy}", DateTimeOffset.UtcNow); @@ -465,7 +465,7 @@ For more information on `DateTime` and `DateTimeOffset` formatting, see [Custom #### Examples -These examples show how to format a message template using the `{}` placeholder syntax. Additionally, an example of escaping the `{}` placeholder syntax is shown with its output. Finally, string interpolation with templating placeholders is also shown: +The following examples show how to format a message template using the `{}` placeholder syntax. Additionally, an example of escaping the `{}` placeholder syntax is shown with its output. Finally, string interpolation with templating placeholders is also shown: ```csharp logger.LogInformation("Number: {Number}", 1); // Number: 1 @@ -507,7 +507,7 @@ Exception logging is provider-specific. If the default log level isn't set, the default log level value is `Information`. -For example, consider this worker service app: +For example, consider the following worker service app: - Created with the .NET Worker templates. - *appsettings.json* and *appsettings.Development.json* deleted or renamed. @@ -629,7 +629,7 @@ The preceding code relies on two NuGet packages: - [Microsoft.Extensions.Hosting](https://www.nuget.org/packages/Microsoft.Extensions.Hosting) - [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging) -Its project file looks similar to this: +Its project file looks similar to the following: ```xml diff --git a/docs/core/tutorials/index.md b/docs/core/tutorials/index.md index b25bb4c99fb65..4306002e1e468 100644 --- a/docs/core/tutorials/index.md +++ b/docs/core/tutorials/index.md @@ -5,11 +5,10 @@ ms.date: 10/23/2025 ai-usage: ai-assisted ms.custom: devdivchpfy22 titleSuffix: "" -ai-usage: ai-assisted --- # Learn .NET and the .NET SDK tools by exploring these tutorials -These tutorials show how to develop console apps and libraries for .NET Core, .NET 5, and later versions. For other types of applications, see [Tutorials for getting started with .NET](../../standard/get-started.md). +The following tutorials show how to develop console apps and libraries for .NET Core, .NET 5, and later versions. For other types of applications, see [Tutorials for getting started with .NET](../../standard/get-started.md). ## Use Visual Studio diff --git a/docs/standard/assembly/index.md b/docs/standard/assembly/index.md index 973adb6daea9d..8b90636687084 100644 --- a/docs/standard/assembly/index.md +++ b/docs/standard/assembly/index.md @@ -83,7 +83,7 @@ Assemblies contain information about content, versioning, and dependencies. So t To use an assembly in an application, you must add a reference to it. When an assembly is referenced, all the accessible types, properties, methods, and other members of its namespaces are available to your application as if their code were part of your source file. > [!NOTE] -> Most assemblies from the .NET Class Library are referenced automatically. If a system assembly isn't automatically referenced, add a reference in one of these ways: +> Most assemblies from the .NET Class Library are referenced automatically. If a system assembly isn't automatically referenced, add a reference in one of the following ways: > > - For .NET and .NET Core, add a reference to the NuGet package that contains the assembly. Either use the NuGet Package Manager in Visual Studio or add a [\](../../core/tools/dependencies.md#the-packagereference-element) element for the assembly to the *.csproj* or *.vbproj* project. > - For .NET Framework, add a reference to the assembly using the **Add Reference** dialog in Visual Studio or the `-reference` command line option for the [C#](../../csharp/language-reference/compiler-options/inputs.md#references) or [Visual Basic](../../visual-basic/reference/command-line-compiler/reference.md) compilers. diff --git a/docs/standard/clr.md b/docs/standard/clr.md index 0366187e77dfb..b1948b3380f71 100644 --- a/docs/standard/clr.md +++ b/docs/standard/clr.md @@ -36,7 +36,7 @@ The common language runtime makes it easy to design components and applications As part of their metadata, all managed components carry information about the components and resources they were built against. The runtime uses this information to ensure that your component or application has the specified versions of everything it needs, which makes your code less likely to break because of some unmet dependency. Registration information and state data are no longer stored in the registry, where they can be difficult to establish and maintain. Instead, information about the types you define and their dependencies is stored with the code as metadata. This way, the task of component replication and removal is less complicated. -Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. Some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you're a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before. The runtime provides these benefits: +Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. Some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you're a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before. The runtime provides the following benefits: - Performance improvements. diff --git a/docs/standard/commandline/index.md b/docs/standard/commandline/index.md index c1105328bf4ba..e2d747b67e00e 100644 --- a/docs/standard/commandline/index.md +++ b/docs/standard/commandline/index.md @@ -36,12 +36,12 @@ The library is available as a NuGet package: [System.CommandLine](https://www.nu ## Next steps -To get started with System.CommandLine, see these resources: +To get started with System.CommandLine, see the following resources: - [Tutorial: Get started with System.CommandLine](get-started-tutorial.md) - [Syntax overview: commands, options, and arguments](syntax.md) -To learn more, see these resources: +To learn more, see the following resources: - [How to parse and invoke the result](how-to-parse-and-invoke.md) - [How to customize parsing and validation](how-to-customize-parsing-and-validation.md) diff --git a/docs/standard/garbage-collection/fundamentals.md b/docs/standard/garbage-collection/fundamentals.md index 0a88a4c70a160..64285b55440fc 100644 --- a/docs/standard/garbage-collection/fundamentals.md +++ b/docs/standard/garbage-collection/fundamentals.md @@ -51,7 +51,7 @@ The following list summarizes important CLR memory concepts: | Reserved | The block of memory is available for your use and can't be used for any other allocation request. However, you can't store data to this memory block until it's committed. | | Committed | The block of memory is assigned to physical storage. | -- Virtual address space can get fragmented, which means that there are free blocks known as holes in the address space. When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy the allocation request. Even if you have 2 GB of free space, an allocation that requires 2 GB is unsuccessful unless all of that free space is in a single address block. +- Virtual address space can get fragmented, which means that there are free blocks known as holes in the address space. When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy the allocation request. Even if you have 2 GB of free space, an allocation that requires 2 GB will be unsuccessful unless all of that free space is in a single address block. - You can run out of memory if there isn't enough virtual address space to reserve or physical space to commit. @@ -59,7 +59,7 @@ The following list summarizes important CLR memory concepts: ### Memory allocation -When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap is allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the runtime allocates memory for it in the address space immediately following the first object. As long as address space is available, the runtime continues to allocate space for new objects in this manner. +When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the runtime allocates memory for it in the address space immediately following the first object. As long as address space is available, the runtime continues to allocate space for new objects in this manner. Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it's almost as fast as allocating memory from the stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects quickly. diff --git a/docs/standard/io/how-to-write-text-to-a-file.md b/docs/standard/io/how-to-write-text-to-a-file.md index 2d86130006b44..d93eeabdd04ef 100644 --- a/docs/standard/io/how-to-write-text-to-a-file.md +++ b/docs/standard/io/how-to-write-text-to-a-file.md @@ -18,7 +18,7 @@ ai-usage: ai-assisted This article shows different ways to write text to a file for a .NET app. -These classes and methods are typically used to write text to a file: +The following classes and methods are typically used to write text to a file: - contains methods to write to a file synchronously ( and ) or asynchronously ( and ). @@ -31,28 +31,28 @@ These classes and methods are typically used to write text to a file: ## Example: Synchronously write text with StreamWriter -This example shows how to use the class to synchronously write text to a new file one line at a time. Because the object is declared and instantiated in a `using` statement, the method is invoked, which automatically flushes and closes the stream. +The following example shows how to use the class to synchronously write text to a new file one line at a time. Because the object is declared and instantiated in a `using` statement, the method is invoked, which automatically flushes and closes the stream. [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/write.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/write.vb)] ## Example: Synchronously append text with StreamWriter -This example shows how to use the class to synchronously append text to the text file created in the first example: +The following example shows how to use the class to synchronously append text to the text file created in the first example: [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/append.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/append.vb)] ## Example: Asynchronously write text with StreamWriter -This example shows how to asynchronously write text to a new file using the class. To invoke the method, the method call must be within an `async` method. +The following example shows how to asynchronously write text to a new file using the class. To invoke the method, the method call must be within an `async` method. [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/async.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/async.vb)] ## Example: Write and append text with the File class -This example shows how to write text to a new file and append new lines of text to the same file using the class. The and methods open and close the file automatically. If the path you provide to the method already exists, the file is overwritten. +The following example shows how to write text to a new file and append new lines of text to the same file using the class. The and methods open and close the file automatically. If the path you provide to the method already exists, the file is overwritten. [!code-csharp[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.basicio.textfiles/cs/file.cs)] [!code-vb[Conceptual.BasicIO.TextFiles#WriteLine](../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.basicio.textfiles/vb/file.vb)] diff --git a/docs/standard/serialization/system-text-json/converters-how-to.md b/docs/standard/serialization/system-text-json/converters-how-to.md index 3483a6e28d02b..05ebc619964d8 100644 --- a/docs/standard/serialization/system-text-json/converters-how-to.md +++ b/docs/standard/serialization/system-text-json/converters-how-to.md @@ -103,7 +103,7 @@ If you throw a `JsonException` without a message, the serializer creates a messa ```output Unhandled exception. System.Text.Json.JsonException: -The JSON value couldn't be converted to System.Object. +The JSON value could not be converted to System.Object. Path: $.Date | LineNumber: 1 | BytePositionInLine: 37. ``` From 8d71a13618b8b42e19bb6fff58211356b2a04abb Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 13:18:15 -0700 Subject: [PATCH 26/30] Update docs/core/extensions/logging.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/extensions/logging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index c1f6119e35793..107dbe4655622 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -322,7 +322,7 @@ The following table lists the value |--|--|--|--| | [Trace](xref:Microsoft.Extensions.Logging.LogLevel) | 0 | | Contain the most detailed messages. These messages might contain sensitive app data. These messages are disabled by default and should ***not*** be enabled in production. | | [Debug](xref:Microsoft.Extensions.Logging.LogLevel) | 1 | | For debugging and development. Use with caution in production due to the high volume. | -| [Information](xref:Microsoft.Extensions.Logging.LogLevel) | 2 | | Tracks the general flow of the app. Can have long-term value. | +| [Information](xref:Microsoft.Extensions.Logging.LogLevel) | 2 | | Tracks the general flow of the app. Might have long-term value. | | [Warning](xref:Microsoft.Extensions.Logging.LogLevel) | 3 | | For abnormal or unexpected events. Typically includes errors or conditions that don't cause the app to fail. | | [Error](xref:Microsoft.Extensions.Logging.LogLevel) | 4 | | For errors and exceptions that can't be handled. These messages indicate a failure in the current operation or request, not an app-wide failure. | | [Critical](xref:Microsoft.Extensions.Logging.LogLevel) | 5 | | For failures that require immediate attention. Examples: data loss scenarios, out of disk space. | From 39c35d83dc3c3852c6d699bd01221298f18c5c41 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 13:18:49 -0700 Subject: [PATCH 27/30] Update docs/core/extensions/logging.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/extensions/logging.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index 107dbe4655622..86727f0939b2a 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -214,7 +214,9 @@ echo $Logging__LogLevel__Microsoft # Or use printenv: # printenv Logging__LogLevel__Microsoft -```> [!NOTE] +``` + +> [!NOTE] > When configuring environment variables with names that contain `.` (periods), see the "Exporting a variable with a dot (.) in it" question on **Stack Exchange** and its corresponding [accepted answer](https://unix.stackexchange.com/a/93533). --- From 1ad3f83f9303ce46c13f5f029190e9b5187bb362 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 13:19:13 -0700 Subject: [PATCH 28/30] Update docs/core/extensions/logging.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/extensions/logging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/extensions/logging.md b/docs/core/extensions/logging.md index 86727f0939b2a..530b9c6843539 100644 --- a/docs/core/extensions/logging.md +++ b/docs/core/extensions/logging.md @@ -239,7 +239,7 @@ For more information on setting .NET configuration values using environment vari ### Configure logging with code -To configure logging in code, use the API. Access it from different places: +To configure logging in code, use the API. You can access it from different places: - When creating the `ILoggerFactory` directly, configure in . - When using DI without a host, configure in . From f3eeae24f84c8256a32c44c3d990b05092a9ed0a Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 13:19:34 -0700 Subject: [PATCH 29/30] Update docs/core/versions/selection.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/core/versions/selection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/versions/selection.md b/docs/core/versions/selection.md index d364775f57281..23fad0a395ed4 100644 --- a/docs/core/versions/selection.md +++ b/docs/core/versions/selection.md @@ -95,7 +95,7 @@ A few usage examples demonstrate the behavior, if you target 5.0: - ✔️ 5.0 is specified. No 5.0.* versions are installed. 5.1.0 is the highest runtime version installed. 5.1.0 is used. - ❌ 3.0 is specified. No 3.x versions are installed. 5.0.0 is the highest runtime installed. An error message is displayed. -Minor version roll-forward has one side-effect that can affect end users. Consider the following scenario: +Minor version roll-forward has one side-effect that might affect end users. Consider the following scenario: 01. The application specifies that 5.0 is required. 02. When run, version 5.0.* isn't installed, however, 5.1.0 is. Version 5.1.0 is used. From 3636ee830b2ba35a0108dfc8a92b75c8a7a3a5e9 Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Mon, 27 Oct 2025 13:19:55 -0700 Subject: [PATCH 30/30] Update docs/standard/base-types/formatting-types.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/standard/base-types/formatting-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/base-types/formatting-types.md b/docs/standard/base-types/formatting-types.md index 270966bb303e8..6cd13b8a0b688 100644 --- a/docs/standard/base-types/formatting-types.md +++ b/docs/standard/base-types/formatting-types.md @@ -217,7 +217,7 @@ The interface includes one method, is a callback method. When you call a `ToString` method overload that includes an parameter, it calls the method of that object. The method is responsible for returning an object that provides the necessary formatting information, as specified by its `formatType` parameter, to the `ToString` method. -Many formatting or string conversion methods include a parameter of type , but in many cases the value of the parameter is ignored when the method is called. The following table lists some of the formatting methods that use the parameter and the type of the object that they pass to the method. +Several formatting or string conversion methods include a parameter of type , but in many cases the value of the parameter is ignored when the method is called. The following table lists some of the formatting methods that use the parameter and the type of the object that they pass to the method. |Method|Type of `formatType` parameter| |------------|------------------------------------|