Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,194 changes: 611 additions & 583 deletions .openpublishing.redirection.csharp.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/core/extensions/logging/library-guidance.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ For more information, see [Compile-time logging source generation](source-genera

## Avoid string interpolation in logging

A common mistake is to use [string interpolation](../../../csharp/tutorials/string-interpolation.md) to build log messages. String interpolation in logging is problematic for performance, as the string is evaluated even if the corresponding `LogLevel` isn't enabled. Instead of string interpolation, use the log message template, formatting, and argument list. For more information, see [Logging in .NET: Log message template](overview.md#log-message-template).
A common mistake is to use [string interpolation](../../../csharp/fundamentals/tutorials/string-interpolation.md) to build log messages. String interpolation in logging is problematic for performance, as the string is evaluated even if the corresponding `LogLevel` isn't enabled. Instead of string interpolation, use the log message template, formatting, and argument list. For more information, see [Logging in .NET: Log message template](overview.md#log-message-template).

## Use no-op logging defaults

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ai-usage: ai-assisted
# Nullable migration strategies

> [!TIP]
> **Starting a new project?** New projects created from .NET 6 or later templates already have `<Nullable>enable</Nullable>` set. You don't need a migration strategy: skip to [Resolve nullable warnings](../../fundamentals/null-safety/resolve-warnings.md).
> **Starting a new project?** New projects created from .NET 6 or later templates already have `<Nullable>enable</Nullable>` set. You don't need a migration strategy: skip to [Resolve nullable warnings](../../fundamentals/null-safety/common-tasks/resolve-warnings.md).
>
> **Maintaining an existing codebase?** Read [Nullable reference types](../../fundamentals/null-safety/nullable-reference-types.md) first to understand contexts, annotations, and null-state. This article assumes you're familiar with those concepts and ready to plan a rollout.

Expand Down Expand Up @@ -49,7 +49,7 @@ The most predictable way to migrate a large project is to enable warnings or ann

1. Pick a file. Start with the deepest leaf types in your dependency graph, then move outward. Annotating a type causes new warnings in its callers, so working bottom-up minimizes rework.
1. Add the `#nullable` directive that opts the file into the new behavior. Use `#nullable enable` if you want both flags. Use `#nullable enable warnings` for warning-only.
1. Address the warnings in the file using the techniques in [Resolve nullable warnings](../../fundamentals/null-safety/resolve-warnings.md).
1. Address the warnings in the file using the techniques in [Resolve nullable warnings](../../fundamentals/null-safety/common-tasks/resolve-warnings.md).
1. Repeat for the next file.
1. When every file in the project has its directive, remove the directives and set `<Nullable>enable</Nullable>` at the project level.

Expand All @@ -71,7 +71,7 @@ Lead with warnings when fixing latent <xref:System.NullReferenceException?displa
Lead with annotations when stabilizing the public API surface is the priority. This sequence suits libraries: you can ship annotated signatures so consumers see the right contracts, then close out the internal warnings on your own schedule.

1. **Phase 1: Add annotations.** Set the project default to `annotations`. Reference types become non-nullable by default, but the compiler doesn't emit warnings, so the noise stays out of your way. Walk the public API and add `?` to every member that may legitimately return or accept `null`. Tighten the signatures that shouldn't. Because warnings are off, you can settle the API shape in focused commits without untangling the implementation at the same time.
1. **Phase 2: Address warnings.** Switch the project default to `enable`. The annotations you added in phase 1 now feed null-state analysis, so the warnings the compiler emits are higher quality from the start: each one points at code whose behavior doesn't match the contract you already published. Resolve them with the techniques in [Resolve nullable warnings](../../fundamentals/null-safety/resolve-warnings.md).
1. **Phase 2: Address warnings.** Switch the project default to `enable`. The annotations you added in phase 1 now feed null-state analysis, so the warnings the compiler emits are higher quality from the start: each one points at code whose behavior doesn't match the contract you already published. Resolve them with the techniques in [Resolve nullable warnings](../../fundamentals/null-safety/common-tasks/resolve-warnings.md).

### Choosing between the orderings

Expand All @@ -96,11 +96,11 @@ After every file participates in the project default and the `<Nullable>enable</
- Remove `null!` and `default!` initializers that you added only to silence warnings during migration. Replace them with proper initialization, or make type a nullable reference type.
- Spot-check the public API. Every member that returns or accepts `null` should be annotated with `?`. The annotations are part of your contract once the package ships.

You're now in the same state as new projects: nullable reference types are part of the type system, and any new warnings reflect a real mismatch between declarations and code. Use [Resolve nullable warnings](../../fundamentals/null-safety/resolve-warnings.md) to address them as they come up.
You're now in the same state as new projects: nullable reference types are part of the type system, and any new warnings reflect a real mismatch between declarations and code. Use [Resolve nullable warnings](../../fundamentals/null-safety/common-tasks/resolve-warnings.md) to address them as they come up.

## Related content

- [Nullable reference types](../../fundamentals/null-safety/nullable-reference-types.md)
- [Resolve nullable warnings](../../fundamentals/null-safety/resolve-warnings.md)
- [Resolve nullable warnings](../../fundamentals/null-safety/common-tasks/resolve-warnings.md)
- [Nullable static analysis attributes](../../language-reference/attributes/nullable-analysis.md)
- [Working with nullable reference types in EF Core](/ef/core/miscellaneous/nullable-reference-types)
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ ai-usage: ai-assisted
# Resolve nullable warnings

> [!TIP]
> **New to nullable reference types?** Read [Nullable reference types](nullable-reference-types.md) first to understand annotations and null-state analysis. This article assumes you're seeing warnings in a project where the feature is enabled.
> **New to nullable reference types?** Read [Nullable reference types](../nullable-reference-types.md) first to understand annotations and null-state analysis. This article assumes you're seeing warnings in a project where the feature is enabled.
>
> **Looking for a specific compiler error code?** The [Resolve nullable warnings](../../language-reference/compiler-messages/nullable-warnings.md) reference article catalogs every CS86xx warning with the matching technique.
> **Looking for a specific compiler error code?** The [Resolve nullable warnings](../../../language-reference/compiler-messages/nullable-warnings.md) reference article catalogs every CS86xx warning with the matching technique.

When you enable nullable reference types, the compiler issues warnings everywhere your code's behavior doesn't match its annotations. Most warnings fall into a small set of patterns. Once you recognize the pattern, the fix is usually one of five techniques:

Expand Down Expand Up @@ -42,13 +42,13 @@ The fix is usually a *guard clause*. A *guard clause* is a check at the top of a

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="DereferenceFixed":::

[Pattern matching](../../language-reference/operators/patterns.md) (expressions such as `is null` or `is { }` that test the shape of a value), `??`, and `??=` include null checks:
[Pattern matching](../../../language-reference/operators/patterns.md) (expressions such as `is null` or `is { }` that test the shape of a value), `??`, and `??=` include null checks:

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="NullOperatorsFix":::

The property pattern `{ Length: > 0 }` matches only when `message` is non-null *and* its `Length` property is greater than zero, so the compiler treats `message` as *not-null* inside the `if` block. A simpler `is not null` test produces the same null-state narrowing without inspecting any properties.

For an in-depth tour of the operators, see [Null operators](null-operators.md).
For an in-depth tour of the operators, see [Null operators](../null-operators.md).

## Adjust annotations

Expand All @@ -73,7 +73,7 @@ Sometimes the right fix isn't at the call site. A method's signature doesn't cap

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="MissingAttribute":::

The body of `IsPresent` proves the argument isn't null when the method returns `true`, but the signature doesn't say so. Add a [nullable analysis attribute](../../language-reference/attributes/nullable-analysis.md) to make the contract part of the API:
The body of `IsPresent` proves the argument isn't null when the method returns `true`, but the signature doesn't say so. Add a [nullable analysis attribute](../../../language-reference/attributes/nullable-analysis.md) to make the contract part of the API:

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="WithAttribute":::

Expand All @@ -84,21 +84,21 @@ Common attributes include:
- <xref:System.Diagnostics.CodeAnalysis.MemberNotNullAttribute> — the listed members are *not-null* after the method returns.
- <xref:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute> — the method never returns normally (for example, it always throws).

The full list is in [Nullable static analysis attributes](../../language-reference/attributes/nullable-analysis.md).
The full list is in [Nullable static analysis attributes](../../../language-reference/attributes/nullable-analysis.md).

## Initialize non-nullable members

A constructor warning means a non-nullable field, property, or [auto-property](../../programming-guide/classes-and-structs/auto-implemented-properties.md) (a property that uses the compiler-generated backing field, such as `public string Name { get; set; }`) exits the constructor without being assigned a non-null value:
A constructor warning means a non-nullable field, property, or [auto-property](../../../programming-guide/classes-and-structs/auto-implemented-properties.md) (a property that uses the compiler-generated backing field, such as `public string Name { get; set; }`) exits the constructor without being assigned a non-null value:

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="UninitializedMember":::

You have several ways to address it. Pick the one that best matches your design intent.

**Require the value as a constructor argument.** Use a [primary constructor](../../whats-new/tutorials/primary-constructors.md) (parameters declared on the type itself, available throughout the body) or a regular constructor that initializes the property:
**Require the value as a constructor argument.** Use a [primary constructor](../../../whats-new/tutorials/primary-constructors.md) (parameters declared on the type itself, available throughout the body) or a regular constructor that initializes the property:

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="ConstructorInjected":::

**Make the property `required`.** The caller must initialize it through an [object initializer](../../programming-guide/classes-and-structs/object-and-collection-initializers.md) (the `{ Property = value }` syntax that follows `new`):
**Make the property `required`.** The caller must initialize it through an [object initializer](../../../programming-guide/classes-and-structs/object-and-collection-initializers.md) (the `{ Property = value }` syntax that follows `new`):

:::code language="csharp" source="snippets/resolve-warnings/Program.cs" id="RequiredMember":::

Expand All @@ -123,18 +123,18 @@ New C# projects enable nullable reference types by default, so most code you wri

The common supported values are `enable` (the default for new projects) and `disable`. If the element is missing, the project uses whatever default the SDK and target framework set.

If you need to enable nullable for only part of a file with `#nullable` directives, or use the partial `warnings` and `annotations` modes when migrating an existing codebase, see [Nullable migration strategies](../../advanced-topics/update-applications/nullable-migration-strategies.md).
If you need to enable nullable for only part of a file with `#nullable` directives, or use the partial `warnings` and `annotations` modes when migrating an existing codebase, see [Nullable migration strategies](../../../advanced-topics/update-applications/nullable-migration-strategies.md).

## Where to go next

When a warning doesn't fit any of these patterns, the [Resolve nullable warnings](../../language-reference/compiler-messages/nullable-warnings.md) reference article lists the technique for every CS86xx warning the compiler emits.
When a warning doesn't fit any of these patterns, the [Resolve nullable warnings](../../../language-reference/compiler-messages/nullable-warnings.md) reference article lists the technique for every CS86xx warning the compiler emits.

To plan a migration that progressively enables nullable reference types in an existing codebase, see [Nullable migration strategies](../../advanced-topics/update-applications/nullable-migration-strategies.md).
To plan a migration that progressively enables nullable reference types in an existing codebase, see [Nullable migration strategies](../../../advanced-topics/update-applications/nullable-migration-strategies.md).

## Related content

- [Nullable reference types](nullable-reference-types.md)
- [Null operators](null-operators.md)
- [Nullable migration strategies](../../advanced-topics/update-applications/nullable-migration-strategies.md)
- [Nullable static analysis attributes](../../language-reference/attributes/nullable-analysis.md)
- [Resolve nullable warnings (compiler reference)](../../language-reference/compiler-messages/nullable-warnings.md)
- [Nullable reference types](../nullable-reference-types.md)
- [Null operators](../null-operators.md)
- [Nullable migration strategies](../../../advanced-topics/update-applications/nullable-migration-strategies.md)
- [Nullable static analysis attributes](../../../language-reference/attributes/nullable-analysis.md)
- [Resolve nullable warnings (compiler reference)](../../../language-reference/compiler-messages/nullable-warnings.md)
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Initialize array elements as part of creating the array. [Collection expressions
## Related content

- [Tutorial: Express your design intent with nullable and non-nullable reference types](../tutorials/nullable-reference-types.md)
- [Resolve nullable warnings](resolve-warnings.md)
- [Resolve nullable warnings](./common-tasks/resolve-warnings.md)
- [Nullable migration strategies](../../advanced-topics/update-applications/nullable-migration-strategies.md)
- [Nullable static analysis attributes](../../language-reference/attributes/nullable-analysis.md)
- [Resolve nullable warnings (compiler reference)](../../language-reference/compiler-messages/nullable-warnings.md)
Loading
Loading