From 6217577aa116271340253596c9e4f590fe4f5055 Mon Sep 17 00:00:00 2001 From: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Date: Fri, 13 Dec 2024 06:33:39 -0800 Subject: [PATCH 1/3] Update package index with latest published versions (#43953) --- docs/azure/includes/dotnet-all.md | 4 ++-- docs/azure/includes/dotnet-new.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md index f2ebb3151068c..ee11da8b37c76 100644 --- a/docs/azure/includes/dotnet-all.md +++ b/docs/azure/includes/dotnet-all.md @@ -187,7 +187,7 @@ | Resource Management - Chaos | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.Chaos/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Chaos/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Chaos-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Chaos_1.0.0/sdk/chaos/Azure.ResourceManager.Chaos/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Chaos_1.1.0-beta.1/sdk/chaos/Azure.ResourceManager.Chaos/) | | Resource Management - Cognitive Services | NuGet [1.4.0](https://www.nuget.org/packages/Azure.ResourceManager.CognitiveServices/1.4.0) | [docs](/dotnet/api/overview/azure/ResourceManager.CognitiveServices-readme) | GitHub [1.4.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.CognitiveServices_1.4.0/sdk/cognitiveservices/Azure.ResourceManager.CognitiveServices/) | | Resource Management - Communication | NuGet [1.2.0](https://www.nuget.org/packages/Azure.ResourceManager.Communication/1.2.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Communication-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Communication_1.2.0/sdk/communication/Azure.ResourceManager.Communication/) | -| Resource Management - Compute | NuGet [1.6.0](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.6.0)
NuGet [1.7.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.7.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.6.0/sdk/compute/Azure.ResourceManager.Compute/)
GitHub [1.7.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.7.0-beta.1/sdk/compute/Azure.ResourceManager.Compute/) | +| Resource Management - Compute | NuGet [1.6.0](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.6.0)
NuGet [1.7.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.7.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.6.0/sdk/compute/Azure.ResourceManager.Compute/)
GitHub [1.7.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.7.0-beta.2/sdk/compute/Azure.ResourceManager.Compute/) | | Resource Management - Computefleet | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeFleet/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeFleet-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeFleet_1.0.0/sdk/computefleet/Azure.ResourceManager.ComputeFleet/) | | Resource Management - Computeschedule | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeSchedule-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.0.0-beta.1/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/) | | Resource Management - Confidential Ledger | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.ConfidentialLedger/1.0.1)
NuGet [1.1.0-beta.4](https://www.nuget.org/packages/Azure.ResourceManager.ConfidentialLedger/1.1.0-beta.4) | [docs](/dotnet/api/overview/azure/ResourceManager.ConfidentialLedger-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ConfidentialLedger_1.0.1/sdk/confidentialledger/Azure.ResourceManager.ConfidentialLedger/)
GitHub [1.1.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ConfidentialLedger_1.1.0-beta.4/sdk/confidentialledger/Azure.ResourceManager.ConfidentialLedger/) | @@ -286,7 +286,7 @@ | Resource Management - MySQL | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.MySql/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.MySql-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.MySql_1.1.0/sdk/mysql/Azure.ResourceManager.MySql/) | | Resource Management - Neonpostgres | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.NeonPostgres/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.NeonPostgres-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NeonPostgres_1.0.0-beta.1/sdk/neonpostgres/Azure.ResourceManager.NeonPostgres/) | | Resource Management - NetApp Files | NuGet [1.8.0](https://www.nuget.org/packages/Azure.ResourceManager.NetApp/1.8.0) | [docs](/dotnet/api/overview/azure/ResourceManager.NetApp-readme) | GitHub [1.8.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetApp_1.8.0/sdk/netapp/Azure.ResourceManager.NetApp/) | -| Resource Management - Network | NuGet [1.9.0](https://www.nuget.org/packages/Azure.ResourceManager.Network/1.9.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Network-readme) | GitHub [1.9.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Network_1.9.0/sdk/network/Azure.ResourceManager.Network/) | +| Resource Management - Network | NuGet [1.9.0](https://www.nuget.org/packages/Azure.ResourceManager.Network/1.9.0)
NuGet [1.10.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Network/1.10.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Network-readme) | GitHub [1.9.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Network_1.9.0/sdk/network/Azure.ResourceManager.Network/)
GitHub [1.10.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Network_1.10.0-beta.1/sdk/network/Azure.ResourceManager.Network/) | | Resource Management - Network Analytics | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.NetworkAnalytics/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.NetworkAnalytics-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkAnalytics_1.0.0/sdk/networkanalytics/Azure.ResourceManager.NetworkAnalytics/) | | Resource Management - Network Cloud | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.NetworkCloud/1.0.1)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.NetworkCloud/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.NetworkCloud-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkCloud_1.0.1/sdk/networkcloud/Azure.ResourceManager.NetworkCloud/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkCloud_1.1.0-beta.1/sdk/networkcloud/Azure.ResourceManager.NetworkCloud/) | | Resource Management - Network Function | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.ResourceManager.NetworkFunction/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/ResourceManager.NetworkFunction-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkFunction_1.0.0-beta.4/sdk/networkfunction/Azure.ResourceManager.NetworkFunction/) | diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md index 8a20e012ff644..0d6cfec4f9a95 100644 --- a/docs/azure/includes/dotnet-new.md +++ b/docs/azure/includes/dotnet-new.md @@ -193,7 +193,7 @@ | Resource Management - Chaos | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.Chaos/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Chaos/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Chaos-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Chaos_1.0.0/sdk/chaos/Azure.ResourceManager.Chaos/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Chaos_1.1.0-beta.1/sdk/chaos/Azure.ResourceManager.Chaos/) | | Resource Management - Cognitive Services | NuGet [1.4.0](https://www.nuget.org/packages/Azure.ResourceManager.CognitiveServices/1.4.0) | [docs](/dotnet/api/overview/azure/ResourceManager.CognitiveServices-readme) | GitHub [1.4.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.CognitiveServices_1.4.0/sdk/cognitiveservices/Azure.ResourceManager.CognitiveServices/) | | Resource Management - Communication | NuGet [1.2.0](https://www.nuget.org/packages/Azure.ResourceManager.Communication/1.2.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Communication-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Communication_1.2.0/sdk/communication/Azure.ResourceManager.Communication/) | -| Resource Management - Compute | NuGet [1.6.0](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.6.0)
NuGet [1.7.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.7.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.6.0/sdk/compute/Azure.ResourceManager.Compute/)
GitHub [1.7.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.7.0-beta.1/sdk/compute/Azure.ResourceManager.Compute/) | +| Resource Management - Compute | NuGet [1.6.0](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.6.0)
NuGet [1.7.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.7.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.6.0/sdk/compute/Azure.ResourceManager.Compute/)
GitHub [1.7.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.7.0-beta.2/sdk/compute/Azure.ResourceManager.Compute/) | | Resource Management - Computefleet | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeFleet/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeFleet-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeFleet_1.0.0/sdk/computefleet/Azure.ResourceManager.ComputeFleet/) | | Resource Management - Computeschedule | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeSchedule-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.0.0-beta.1/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/) | | Resource Management - Confidential Ledger | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.ConfidentialLedger/1.0.1)
NuGet [1.1.0-beta.4](https://www.nuget.org/packages/Azure.ResourceManager.ConfidentialLedger/1.1.0-beta.4) | [docs](/dotnet/api/overview/azure/ResourceManager.ConfidentialLedger-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ConfidentialLedger_1.0.1/sdk/confidentialledger/Azure.ResourceManager.ConfidentialLedger/)
GitHub [1.1.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ConfidentialLedger_1.1.0-beta.4/sdk/confidentialledger/Azure.ResourceManager.ConfidentialLedger/) | @@ -293,7 +293,7 @@ | Resource Management - MySQL | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.MySql/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.MySql-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.MySql_1.1.0/sdk/mysql/Azure.ResourceManager.MySql/) | | Resource Management - Neonpostgres | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.NeonPostgres/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.NeonPostgres-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NeonPostgres_1.0.0-beta.1/sdk/neonpostgres/Azure.ResourceManager.NeonPostgres/) | | Resource Management - NetApp Files | NuGet [1.8.0](https://www.nuget.org/packages/Azure.ResourceManager.NetApp/1.8.0) | [docs](/dotnet/api/overview/azure/ResourceManager.NetApp-readme) | GitHub [1.8.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetApp_1.8.0/sdk/netapp/Azure.ResourceManager.NetApp/) | -| Resource Management - Network | NuGet [1.9.0](https://www.nuget.org/packages/Azure.ResourceManager.Network/1.9.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Network-readme) | GitHub [1.9.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Network_1.9.0/sdk/network/Azure.ResourceManager.Network/) | +| Resource Management - Network | NuGet [1.9.0](https://www.nuget.org/packages/Azure.ResourceManager.Network/1.9.0)
NuGet [1.10.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Network/1.10.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Network-readme) | GitHub [1.9.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Network_1.9.0/sdk/network/Azure.ResourceManager.Network/)
GitHub [1.10.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Network_1.10.0-beta.1/sdk/network/Azure.ResourceManager.Network/) | | Resource Management - Network Analytics | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.NetworkAnalytics/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.NetworkAnalytics-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkAnalytics_1.0.0/sdk/networkanalytics/Azure.ResourceManager.NetworkAnalytics/) | | Resource Management - Network Cloud | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.NetworkCloud/1.0.1)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.NetworkCloud/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.NetworkCloud-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkCloud_1.0.1/sdk/networkcloud/Azure.ResourceManager.NetworkCloud/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkCloud_1.1.0-beta.1/sdk/networkcloud/Azure.ResourceManager.NetworkCloud/) | | Resource Management - Network Function | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.ResourceManager.NetworkFunction/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/ResourceManager.NetworkFunction-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.NetworkFunction_1.0.0-beta.4/sdk/networkfunction/Azure.ResourceManager.NetworkFunction/) | From 4c158be6ef1fad28421980106a9df9d77be69c63 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 13 Dec 2024 14:09:07 -0500 Subject: [PATCH 2/3] Add more clarity on member lookup (#43932) Found while updating the feature spec for the feature. This article didn't clearly state that file local types are preferred over other types with the same name in the file where they are declared. Also, the `file` modifier doesn't actually modify the *scope*, rather, it modifies the *visibility*. Update the language to match the speclet definition. Finally, quick edit pass. --- .../csharp/language-reference/keywords/file.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/csharp/language-reference/keywords/file.md b/docs/csharp/language-reference/keywords/file.md index a2a2d8fef1cb5..fcf926adc3812 100644 --- a/docs/csharp/language-reference/keywords/file.md +++ b/docs/csharp/language-reference/keywords/file.md @@ -1,17 +1,17 @@ --- -description: "file modifier: Declare types whose scope is the file in which it's declared" -title: "file keyword" -ms.date: 09/15/2022 +description: "The file modifier: Declare types whose visibility is the file in which it's declared" +title: "The file keyword" +ms.date: 12/10/2024 f1_keywords: - "file_CSharpKeyword" helpviewer_keywords: - "file keyword [C#]" --- -# file (C# Reference) +# The file modifier Beginning with C# 11, the `file` contextual keyword is a type modifier. -The `file` modifier restricts a top-level type's scope and visibility to the file in which it's declared. The `file` modifier will generally be applied to types written by a source generator. File-local types provide source generators with a convenient way to avoid name collisions among generated types. The `file` modifier declares a file-local type, as in this example: +The `file` modifier restricts a top-level type's visibility to the file in which it's declared. The `file` modifier is most often applied to types written by a source generator. File-local types provide source generators with a convenient way to avoid name collisions among generated types. The `file` modifier declares a file-local type, as in this example: ```csharp file class HiddenWidget @@ -20,11 +20,9 @@ file class HiddenWidget } ``` -Any types nested within a file-local type are also only visible within the file in which it's declared. Other types in an assembly may use the same name as a file-local type. Because the file-local type is visible only in the file where it's declared, these types don't create a naming collision. +Any types nested within a file-local type are also only visible within the file in which it's declared. Other types in an assembly can use the same name as a file-local type. Because the file-local type is visible only in the file where it's declared, these types don't create a naming collision. -A file-local type can't be the return type or parameter type of any member that is more visible than `file` scope. A file-local type can't be a field member of a type that has greater visibility than `file` scope. However, a more visible type may implicitly implement a file-local interface type. The type can also [explicitly implement](../../programming-guide/interfaces/explicit-interface-implementation.md) a file-local interface but explicit implementations can only be used within the `file` scope. - -## Example +A file-local type can't be the return type or parameter type of any member declared in a non file-local type. A file-local type can't be a field member of a non-file-local. However, a more visible type can implicitly implement a file-local interface type. The type can also [explicitly implement](../../programming-guide/interfaces/explicit-interface-implementation.md) a file-local interface but explicit implementations can only be used within the same file. The following example shows a public type that uses a file-local type to provide a worker method. In addition, the public type implements a file-local interface implicitly: @@ -34,6 +32,8 @@ In another source file, you can declare types that have the same names as the fi :::code language="csharp" source="./snippets/Program.cs" id="ShadowsFileScopedType"::: +Member lookup prefers a file-local type declared in the same file over a non-file-local type declared in a different file. This rule ensures that a source generator can rely on member lookup resolving to a file-local type without ambiguity with other type declarations. In the preceding example, all uses of `HiddenWidget` in *File1.cs* resolve to the file-local type declared in *File1.cs*. The file-local declaration of `HiddenWidget` hides the public declaration in *File2.cs*. + ## C# language specification For more information, see [Declared accessibility](~/_csharpstandard/standard/basic-concepts.md#752-declared-accessibility) in the [C# Language Specification](~/_csharpstandard/standard/README.md), and the [C# 11 - File local types](~/_csharplang/proposals/csharp-11.0/file-local-types.md) feature specification. From 8995edc3b343dbfbc01a7bf6f8ca3c527f346063 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Fri, 13 Dec 2024 14:17:10 -0500 Subject: [PATCH 3/3] Freshness pass and bug fixes: Nullable reference types (#43914) * Update notes on annotations Update the article to use the language adopted by the C# standards committee to describe the nullable context, and the null state of any variables. * freshness pass and bug fixes Fixes #21941: Add description of the default values for arrays of reference types. Fixes #30348: Edit pass Fixes #33667: Update the description of the nullable context to match the language used in the C# 8 draft standard Fixes #36767: Add language on declaring a non-null array of nullable reference types and a nullable array of non-nullable reference types. Also, perform a general edit pass. * fix warnings * Apply suggestions from code review Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com> --------- Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com> --- .../builtin-types/arrays.md | 24 ++++- .../compiler-options/language.md | 2 +- .../keywords/where-generic-type-constraint.md | 2 +- .../operators/null-forgiving.md | 2 +- docs/csharp/nullable-references.md | 88 +++++++++---------- 5 files changed, 66 insertions(+), 52 deletions(-) diff --git a/docs/csharp/language-reference/builtin-types/arrays.md b/docs/csharp/language-reference/builtin-types/arrays.md index 8ae2af65ac494..a28250802a31d 100644 --- a/docs/csharp/language-reference/builtin-types/arrays.md +++ b/docs/csharp/language-reference/builtin-types/arrays.md @@ -1,7 +1,7 @@ --- -title: "Arrays" +title: "The array reference type" description: Store multiple variables of the same type in an array data structure in C#. Declare an array by specifying a type or specify Object to store any type. -ms.date: 08/24/2023 +ms.date: 12/09/2024 helpviewer_keywords: - "arrays [C#]" - "C# language, arrays" @@ -26,6 +26,24 @@ You can store multiple variables of the same type in an array data structure. Yo type[] arrayName; ``` +An array is a reference type, so the array can be a [nullable reference](../../nullable-references.md) type. The element types might be reference types, so an array can be declared to hold nullable reference types. The following example declarations show the different syntax used to declare the nullability of the array or the elements: + +```csharp +type?[] arrayName; // non nullable array of nullable element types. +type[]? arrayName; // nullable array of non-nullable element types. +type?[]? arrayName; // nullable array of nullable element types. +``` + +Uninitialized elements in an array are set to the default value for that type: + +```csharp +int[] numbers = new int[10]; // All values are 0 +string[] messages = new string[10]; // All values are null. +``` + +> [!IMPORTANT] +> In the preceding example, even though the type is `string[]`, an array of non-nullable strings, the default value for each element is null. The best way to initialize an array to non-null values is to use a [collection expressions](../operators/collection-expressions.md). + An array has the following properties: - An array can be [single-dimensional](#single-dimensional-arrays), [multidimensional](#multidimensional-arrays), or [jagged](#jagged-arrays). @@ -67,7 +85,7 @@ You can pass an initialized single-dimensional array to a method. In the followi ## Multidimensional arrays -Arrays can have more than one dimension. For example, the following declarations create four arrays: two have two dimensions, two have three dimensions. The first two declarations declare the length of each dimension, but don't initialize the values of the array. The second two declarations use an initializer to set the values of each element in the multidimensional array. +Arrays can have more than one dimension. For example, the following declarations create four arrays. Two arrays have have two dimensions. Two arrays have three dimensions. The first two declarations declare the length of each dimension, but don't initialize the values of the array. The second two declarations use an initializer to set the values of each element in the multidimensional array. :::code language="csharp" source="./snippets/shared/Arrays.cs" id="MultiDimensionalArrayDeclaration"::: diff --git a/docs/csharp/language-reference/compiler-options/language.md b/docs/csharp/language-reference/compiler-options/language.md index 728d0ea64991b..02e58125757d9 100644 --- a/docs/csharp/language-reference/compiler-options/language.md +++ b/docs/csharp/language-reference/compiler-options/language.md @@ -149,7 +149,7 @@ The **Nullable** option lets you specify the nullable context. It can be set in enable ``` -The argument must be one of `enable`, `disable`, `warnings`, or `annotations`. The `enable` argument enables the nullable context. Specifying `disable` will disable the nullable context. When you specify the `warnings` argument, the nullable warning context is enabled. When you specify the `annotations` argument, the nullable annotation context is enabled. The values are described and explained in the article on [Nullable contexts](../../nullable-references.md#nullable-contexts). You can learn more about the tasks involved in enabling nullable reference types in an existing codebase in our article on [nullable migration strategies](../../nullable-migration-strategies.md). +The argument must be one of `enable`, `disable`, `warnings`, or `annotations`. The `enable` argument enables the nullable context. Specifying `disable` will disable the nullable context. When you specify the `warnings` argument, the nullable warning context is enabled. When you specify the `annotations` argument, the nullable annotation context is enabled. The values are described and explained in the article on [Nullable contexts](../../nullable-references.md#nullable-context). You can learn more about the tasks involved in enabling nullable reference types in an existing codebase in our article on [nullable migration strategies](../../nullable-migration-strategies.md). > [!NOTE] > When there's no value set, the default value `disable` is applied, however the .NET 6 templates are by default provided with the **Nullable** value set to `enable`. diff --git a/docs/csharp/language-reference/keywords/where-generic-type-constraint.md b/docs/csharp/language-reference/keywords/where-generic-type-constraint.md index 279d63724867d..6e81ba5502889 100644 --- a/docs/csharp/language-reference/keywords/where-generic-type-constraint.md +++ b/docs/csharp/language-reference/keywords/where-generic-type-constraint.md @@ -36,7 +36,7 @@ The `where` clause can specify that the type is a `class` or a `struct`. The `st In a nullable context, the `class` constraint requires a type to be a non-nullable reference type. To allow nullable reference types, use the `class?` constraint, which allows both nullable and non-nullable reference types. -The `where` clause can include the `notnull` constraint. The `notnull` constraint limits the type parameter to non-nullable types. The type can be a [value type](../builtin-types/value-types.md) or a non-nullable reference type. The `notnull` constraint is available for code compiled in a [`nullable enable` context](../../nullable-references.md#nullable-contexts). Unlike other constraints, if a type argument violates the `notnull` constraint, the compiler generates a warning instead of an error. Warnings are only generated in a `nullable enable` context. +The `where` clause can include the `notnull` constraint. The `notnull` constraint limits the type parameter to non-nullable types. The type can be a [value type](../builtin-types/value-types.md) or a non-nullable reference type. The `notnull` constraint is available for code compiled in a [`nullable enable` context](../../nullable-references.md#nullable-context). Unlike other constraints, if a type argument violates the `notnull` constraint, the compiler generates a warning instead of an error. Warnings are only generated in a `nullable enable` context. The addition of nullable reference types introduces a potential ambiguity in the meaning of `T?` in generic methods. If `T` is a `struct`, `T?` is the same as . However, if `T` is a reference type, `T?` means that `null` is a valid value. The ambiguity arises because overriding methods can't include constraints. The new `default` constraint resolves this ambiguity. You add it when a base class or interface declares two overloads of a method, one that specifies the `struct` constraint, and one that doesn't have either the `struct` or `class` constraint applied: diff --git a/docs/csharp/language-reference/operators/null-forgiving.md b/docs/csharp/language-reference/operators/null-forgiving.md index 598e6fade3456..27afb8dc73565 100644 --- a/docs/csharp/language-reference/operators/null-forgiving.md +++ b/docs/csharp/language-reference/operators/null-forgiving.md @@ -10,7 +10,7 @@ helpviewer_keywords: --- # ! (null-forgiving) operator (C# reference) -The unary postfix `!` operator is the null-forgiving, or null-suppression, operator. In an enabled [nullable annotation context](../../nullable-references.md#nullable-contexts), you use the null-forgiving operator to suppress all nullable warnings for the preceding expression. The unary prefix `!` operator is the [logical negation operator](boolean-logical-operators.md#logical-negation-operator-). The null-forgiving operator has no effect at run time. It only affects the compiler's static flow analysis by changing the null state of the expression. At run time, expression `x!` evaluates to the result of the underlying expression `x`. +The unary postfix `!` operator is the null-forgiving, or null-suppression, operator. In an enabled [nullable annotation context](../../nullable-references.md#nullable-context), you use the null-forgiving operator to suppress all nullable warnings for the preceding expression. The unary prefix `!` operator is the [logical negation operator](boolean-logical-operators.md#logical-negation-operator-). The null-forgiving operator has no effect at run time. It only affects the compiler's static flow analysis by changing the null state of the expression. At run time, expression `x!` evaluates to the result of the underlying expression `x`. For more information about the nullable reference types feature, see [Nullable reference types](../builtin-types/nullable-reference-types.md). diff --git a/docs/csharp/nullable-references.md b/docs/csharp/nullable-references.md index 363263380aa99..801c121b5d1ab 100644 --- a/docs/csharp/nullable-references.md +++ b/docs/csharp/nullable-references.md @@ -2,33 +2,27 @@ title: Nullable reference types description: This article provides an overview of nullable reference types. Learn how the feature provides safety against null reference exceptions, for new and existing projects. ms.subservice: null-safety -ms.date: 11/22/2024 +ms.date: 12/09/2024 --- # Nullable reference types -In a nullable-oblivious context, all reference types were nullable. *Nullable reference types* refers to a group of features enabled in a nullable aware context that minimize the likelihood that your code causes the runtime to throw . *Nullable reference types* includes three features that help you avoid these exceptions, including the ability to explicitly mark a reference type as *nullable*: +*Nullable reference types* are a group of features that minimize the likelihood that your code causes the runtime to throw . Three features that help you avoid these exceptions, including the ability to explicitly mark a reference type as *nullable*: - Improved static flow analysis that determines if a variable might be `null` before dereferencing it. - Attributes that annotate APIs so that the flow analysis determines *null-state*. - Variable annotations that developers use to explicitly declare the intended *null-state* for a variable. -The compiler tracks the *null-state* of every expression in your code at compile time. The *null-state* has one of three values: +The compiler tracks the *null-state* of every expression in your code at compile time. The *null-state* has one of two values: - *not-null*: The expression is known to be not-`null`. - *maybe-null*: The expression might be `null`. -- *oblivious*: The compiler can't determine the null-state of the expression. Variable annotations determine the *nullability* of a reference type variable: - *non-nullable*: If you assign a `null` value or a *maybe-null* expression to the variable, the compiler issues a warning. Variables that are *non-nullable* have a default null-state of *not-null*. - *nullable*: You can assign a `null` value or a *maybe-null* expression to the variable. When the variable's null-state is *maybe-null*, the compiler issues a warning if you dereference the variable. The default null-state for the variable is *maybe-null*. -- *oblivious*: You can assign a `null` value or a *maybe-null* expression to the variable. The compiler doesn't issue warnings when you dereference the variable, or when you assign a *maybe-null* expression to the variable. -The *oblivious* null-state and *oblivious* nullability match the behavior before nullable reference types were introduced. Those values are useful during migration, or when your app uses a library that hasn't enabled nullable reference types. - -Null-state analysis and variable annotations are disabled by default for existing projects—meaning that all reference types continue to be nullable. Starting in .NET 6, they're enabled by default for *new* projects. For information about enabling these features by declaring a *nullable annotation context*, see [Nullable contexts](#nullable-contexts). - -The rest of this article describes how those three feature areas work to produce warnings when your code might be **dereferencing** a `null` value. Dereferencing a variable means to access one of its members using the `.` (dot) operator, as shown in the following example: +The rest of this article describes how those three feature areas work to produce warnings when your code might **dereference** a `null` value. Dereferencing a variable means to access one of its members using the `.` (dot) operator, as shown in the following example: ```csharp string message = "Hello, World!"; @@ -63,32 +57,30 @@ You'll learn about: - The compiler's [null-state analysis](#null-state-analysis): how the compiler determines if an expression is not-null, or maybe-null. - [Attributes](#attributes-on-api-signatures) that are applied to APIs that provide more context for the compiler's null-state analysis. -- [Nullable variable annotations](#nullable-variable-annotations) that provide information about your intent for variables. Annotations are useful for fields to set the default null-state at the beginning of member methods. +- [Nullable variable annotations](#nullable-variable-annotations) that provide information about your intent for variables. Annotations are useful for fields, parameters, and return values to set the default null-state. - The rules governing [generic type arguments](#generics). New constraints were added because type parameters can be reference types or value types. The `?` suffix is implemented differently for nullable value types and nullable reference types. -- [Nullable contexts](#nullable-contexts) help you migrate large projects. You can enable nullable contexts or warnings in parts of your app as you migrate. After you address more warnings, you can enable nullable reference types for the entire project. +- The [Nullable context](#nullable-context) help you migrate large projects. You can enable warnings and annotations in the nullable context in parts of your app as you migrate. After you address more warnings, you can enable both settings for the entire project. Finally, you learn known pitfalls for null-state analysis in `struct` types and arrays. You can also explore these concepts in our Learn module on [Nullable safety in C#](/training/modules/csharp-null-safety). -## null-state analysis - -When nullable reference types are enabled, ***Null-state analysis*** tracks the *null-state* of references. An expression is either *not-null* or *maybe-null*. The compiler determines that a variable is *not-null* in two ways: +## Null-state analysis -1. The variable has been assigned a value that is known to be *not-null*. -1. The variable has been checked against `null` and hasn't been modified since that check. +***Null-state analysis*** tracks the *null-state* of references. An expression is either *not-null* or *maybe-null*. The compiler determines that a variable is *not-null* in two ways: -When nullable reference types aren't enabled, all expressions have the null-state of *oblivious*. The rest of the section describes the behavior when nullable reference types are enabled. +1. The variable was assigned a value that is known to be *not-null*. +1. The variable was checked against `null` and wasn't assigned since that check. -Any variable that the compiler hasn't determined as *not-null* is considered *maybe-null*. The analysis provides warnings in situations where you might accidentally dereference a `null` value. The compiler produces warnings based on the *null-state*. +Any variable that the compiler can't determined as *not-null* is considered *maybe-null*. The analysis provides warnings in situations where you might accidentally dereference a `null` value. The compiler produces warnings based on the *null-state*. -- When a variable is *not-null*, that variable might be dereferenced safely. +- When a variable is *not-null*, that variable can be dereferenced safely. - When a variable is *maybe-null*, that variable must be checked to ensure that it isn't `null` before dereferencing it. Consider the following example: ```csharp -string message = null; +string? message = null; // warning: dereference null. Console.WriteLine($"The length of the message is {message.Length}"); @@ -117,7 +109,7 @@ void FindRoot(Node node, Action processNode) The previous code doesn't generate any warnings for dereferencing the variable `current`. Static analysis determines that `current` is never dereferenced when it's *maybe-null*. The variable `current` is checked against `null` before `current.Parent` is accessed, and before passing `current` to the `ProcessNode` action. The previous examples show how the compiler determines *null-state* for local variables when initialized, assigned, or compared to `null`. -The null-state analysis doesn't trace into called methods. As a result, fields initialized in a common helper method called by all constructors generates a warning with the following template: +The null-state analysis doesn't trace into called methods. As a result, fields initialized in a common helper method called by all constructors might generate a warning with the following message: > Non-nullable property '*name*' must contain a non-null value when exiting constructor. @@ -125,7 +117,7 @@ You can address these warnings in one of two ways: *Constructor chaining*, or *n :::code language="csharp" source="./language-reference/compiler-messages/snippets/null-warnings/PersonExamples.cs" id="ConstructorChainingAndMemberNotNull"::: -Nullable state analysis and the warnings the compiler generates help you avoid program errors by dereferencing `null`. The article on [resolving nullable warnings](language-reference/compiler-messages/nullable-warnings.md) provides techniques for correcting the warnings most likely seen in your code. +Nullable state analysis and the warnings the compiler generates help you avoid program errors by dereferencing `null`. The article on [resolving nullable warnings](language-reference/compiler-messages/nullable-warnings.md) provides techniques for correcting the warnings most likely seen in your code. The diagnostics produced from null state analysis are warnings only. ## Attributes on API signatures @@ -163,11 +155,11 @@ You use annotations that can declare whether a variable is a **nullable referenc - The variable must be initialized to a non-null value. - The variable can never be assigned the value `null`. The compiler issues a warning when code assigns a *maybe-null* expression to a variable that shouldn't be null. - **A reference might be null**. The default state of a nullable reference variable is *maybe-null*. The compiler enforces rules to ensure that you correctly check for a `null` reference: - - The variable might only be dereferenced when the compiler can guarantee that the value isn't `null`. - - These variables might be initialized with the default `null` value and might be assigned the value `null` in other code. + - The variable can only be dereferenced when the compiler can guarantee that the value isn't `null`. + - These variables can be initialized with the default `null` value and can be assigned the value `null` in other code. - The compiler doesn't issue warnings when code assigns a *maybe-null* expression to a variable that might be null. -Any non-nullable reference variable has a default *null-state* of *not-null*. Any nullable reference variable has the initial *null-state* of *maybe-null*. +Any non-nullable reference variable has the initial *null-state* of *not-null*. Any nullable reference variable has the initial *null-state* of *maybe-null*. A **nullable reference type** is noted using the same syntax as [nullable value types](language-reference/builtin-types/nullable-value-types.md): a `?` is appended to the type of the variable. For example, the following variable declaration represents a nullable string variable, `name`: @@ -185,7 +177,7 @@ name!.Length; Nullable reference types and nullable value types provide a similar semantic concept: A variable can represent a value or object, or that variable might be `null`. However, nullable reference types and nullable value types are implemented differently: nullable value types are implemented using , and nullable reference types are implemented by attributes read by the compiler. For example, `string?` and `string` are both represented by the same type: . However, `int?` and `int` are represented by `System.Nullable` and , respectively. -Nullable reference types are a compile time feature. That means it's possible for callers to ignore warnings, intentionally use `null` as an argument to a method expecting a non nullable reference. Library authors should include run-time checks against null argument values. The is the preferred option for checking a parameter against null at run time. +Nullable reference types are a compile time feature. That means it's possible for callers to ignore warnings, intentionally use `null` as an argument to a method expecting a non nullable reference. Library authors should include run-time checks against null argument values. The is the preferred option for checking a parameter against null at run time. Furthermore, the runtime behavior of a program making use of nullable annotations is the same if all the nullable annotations, (`?` and `!`), are removed. Their only purpose is expressing design intent and providing information for null state analysis. > [!IMPORTANT] > Enabling nullable annotations can change how Entity Framework Core determines if a data member is required. You can learn more details in the article on [Entity Framework Core Fundamentals: Working with Nullable Reference Types](/ef/core/miscellaneous/nullable-reference-types). @@ -209,7 +201,11 @@ You can specify different behavior using [constraints](programming-guide/generic These constraints help provide more information to the compiler on how `T` is used. That helps when developers choose the type for `T` and provides better *null-state* analysis when an instance of the generic type is used. -## Nullable contexts +## Nullable context + +The *nullable context* determines how nullable reference type annotations are handled and what warnings are produced by static null state analysis. The nullable context contains two flags: the *annotation* setting and the *warning* setting. + +Both the *annotation* and *warning* settings are disabled by default for existing projects. Starting in .NET 6 (C# 10), both flags are enabled by default for *new* projects. The reason for two distinct flags for the nullable context is to make it easier to migrate large projects that predate the introduction of nullable reference types. For small projects, you can enable nullable reference types, fix warnings, and continue. However, for larger projects and multi-project solutions, that might generate a large number of warnings. You can use pragmas to enable nullable reference types file-by-file as you begin using nullable reference types. The new features that protect against throwing a can be disruptive when turned on in an existing codebase: @@ -217,24 +213,24 @@ For small projects, you can enable nullable reference types, fix warnings, and c - The meaning of the `class` constraint in generics changed to mean a non-nullable reference type. - New warnings are generated because of these new rules. -The **nullable annotation context** determines the compiler's behavior. There are four values for the **nullable annotation context**: +The **nullable annotation context** determines the compiler's behavior. There are four combinations for the **nullable context** settings: -- *disable*: The code is *nullable-oblivious*. *Disable* matches the behavior before nullable reference types were enabled, except the new syntax produces warnings instead of errors. +- *both disabled*: The code is *nullable-oblivious*. *Disable* matches the behavior before nullable reference types were enabled, except the new syntax produces warnings instead of errors. - Nullable warnings are disabled. - All reference type variables are nullable reference types. - Use of the `?` suffix to declare a nullable reference type produces a warning. - You can use the null forgiving operator, `!`, but it has no effect. -- *enable*: The compiler enables all null reference analysis and all language features. +- *both enabled*: The compiler enables all null reference analysis and all language features. - All new nullable warnings are enabled. - You can use the `?` suffix to declare a nullable reference type. - Reference type variables without the `?` suffix are non-nullable reference types. - The null forgiving operator suppresses warnings for a possible dereference of `null`. -- *warnings*: The compiler performs all null analysis and emits warnings when code might dereference `null`. +- *warning enabled*: The compiler performs all null analysis and emits warnings when code might dereference `null`. - All new nullable warnings are enabled. - Use of the `?` suffix to declare a nullable reference type produces a warning. - All reference type variables are allowed to be null. However, members have the *null-state* of *not-null* at the opening brace of all methods unless declared with the `?` suffix. - You can use the null forgiving operator, `!`. -- *annotations*: The compiler doesn't emit warnings when code might dereference `null`, or when you assign a maybe-null expression to a non-nullable variable. +- *annotations enabled*: The compiler doesn't emit warnings when code might dereference `null`, or when you assign a maybe-null expression to a non-nullable variable. - All new nullable warnings are disabled. - You can use the `?` suffix to declare a nullable reference type. - Reference type variables without the `?` suffix are non-nullable reference types. @@ -264,21 +260,21 @@ You can choose which setting is best for your project: enable ``` -You can also use directives to set these same contexts anywhere in your source code. These directives are most useful when you're migrating a large codebase. +You can also use directives to set these same flags anywhere in your source code. These directives are most useful when you're migrating a large codebase. -- `#nullable enable`: Sets the nullable annotation context and nullable warning context to **enable**. -- `#nullable disable`: Sets the nullable annotation context and nullable warning context to **disable**. -- `#nullable restore`: Restores the nullable annotation context and nullable warning context to the project settings. -- `#nullable disable warnings`: Set the nullable warning context to **disable**. -- `#nullable enable warnings`: Set the nullable warning context to **enable**. -- `#nullable restore warnings`: Restores the nullable warning context to the project settings. -- `#nullable disable annotations`: Set the nullable annotation context to **disable**. -- `#nullable enable annotations`: Set the nullable annotation context to **enable**. -- `#nullable restore annotations`: Restores the nullable annotation context to the project settings. +- `#nullable enable`: Sets the annotation and warning flags to **enable**. +- `#nullable disable`: Sets the annotation and warning flags to **disable**. +- `#nullable restore`: Restores the annotation flag and warning flag to the project settings. +- `#nullable disable warnings`: Set the warning flag to **disable**. +- `#nullable enable warnings`: Set the warning flag to **enable**. +- `#nullable restore warnings`: Restores the warning flag to the project settings. +- `#nullable disable annotations`: Set the annotation flag to **disable**. +- `#nullable enable annotations`: Set the annotation flag to **enable**. +- `#nullable restore annotations`: Restores the annotation flag to the project settings. For any line of code, you can set any of the following combinations: -| Warning context | Annotation context | Use | +| Warning flag | Annotation flag | Use | |:---------------:|:------------------:|----------------------------------------| | project default | project default | Default | | enable | disable | Fix analysis warnings | @@ -293,7 +289,7 @@ For any line of code, you can set any of the following combinations: Those nine combinations provide you with fine-grained control over the diagnostics the compiler emits for your code. You can enable more features in any area you're updating, without seeing more warnings you aren't ready to address yet. > [!IMPORTANT] -> The global nullable context does not apply for generated code files. Under either strategy, the nullable context is *disabled* for any source file marked as generated. This means any APIs in generated files are not annotated. There are four ways a file is marked as generated: +> The global nullable context does not apply for generated code files. Under either strategy, the nullable context is *disabled* for any source file marked as generated. This means any APIs in generated files are not annotated. No nullable warnings are produced for generated files. There are four ways a file is marked as generated: > > 1. In the .editorconfig, specify `generated_code = true` in a section that applies to that file. > 1. Put `` or `` in a comment at the top of the file. It can be on any line in that comment, but the comment block must be the first element in the file. @@ -302,7 +298,7 @@ Those nine combinations provide you with fine-grained control over the diagnosti > > Generators can opt-in using the [`#nullable`](language-reference/preprocessor-directives.md#nullable-context) preprocessor directive. -By default, nullable annotation and warning contexts are **disabled**. That means that your existing code compiles without changes and without generating any new warnings. Beginning with .NET 6, new projects include the `enable` element in all project templates. +By default, nullable annotation and warning flags are **disabled**. That means that your existing code compiles without changes and without generating any new warnings. Beginning with .NET 6, new projects include the `enable` element in all project templates, setting these flags to **enabled**. These options provide two distinct strategies to [update an existing codebase](nullable-migration-strategies.md) to use nullable reference types.