diff --git a/docfx.json b/docfx.json index 720a602ec581c..ae49b6563579d 100644 --- a/docfx.json +++ b/docfx.json @@ -58,7 +58,8 @@ "unbound-generic-types-in-nameof.md", "first-class-span-types.md", "simple-lambda-parameters-with-modifiers.md", - "partial-events-and-constructors.md" + "partial-events-and-constructors.md", + "null-conditional-assignment.md" ], "src": "_csharplang/proposals", "dest": "csharp/language-reference/proposals", @@ -509,7 +510,7 @@ "_csharplang/proposals/csharp-11.0/*.md": "09/30/2022", "_csharplang/proposals/csharp-12.0/*.md": "08/15/2023", "_csharplang/proposals/csharp-13.0/*.md": "10/31/2024", - "_csharplang/proposals/*.md": "03/11/2025", + "_csharplang/proposals/*.md": "04/04/2025", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "11/08/2022", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "11/08/2023", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "11/09/2024", @@ -689,6 +690,7 @@ "_csharplang/proposals/first-class-span-types.md": "First-class span types", "_csharplang/proposals/simple-lambda-parameters-with-modifiers.md": "Simple lambda parameters with modifiers", "_csharplang/proposals/partial-events-and-constructors.md": "Partial events and constructors", + "_csharplang/proposals/null-conditional-assignment.md": "Null conditional assignment", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "C# compiler breaking changes since C# 10", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "C# compiler breaking changes since C# 11", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "C# compiler breaking changes since C# 12", @@ -812,8 +814,9 @@ "_csharplang/proposals/field-keyword.md": "This proposal introduces a new keyword, `field`, that accesses the compiler generated backing field in a property accessor.", "_csharplang/proposals/unbound-generic-types-in-nameof.md": "This proposal introduces the ability to use unbound generic types such as `List<>` in `nameof` expressions. The type argument isn't required.", "_csharplang/proposals/first-class-span-types.md": "This proposal provides several implicit conversions to `Span` and `ReadOnlySpan` that enable library authors to have fewer overloads and developers to write code that resolves to faster Span based APIs", - "_csharplang/proposals/simple-lambda-parameters-with-modifiers.md": "This proposal provides allows lambda parmaeters to be declared with modifiers without requiring their type names. You can add modifiers like `ref` and `out` to lambda parameters without specifying their type.", - "_csharplang/proposals/partial-events-and-constructors.md": "This proposal provides allows partial events and constructors to be declared in partial classes. This allows the event and constructor to be split across class declarations.", + "_csharplang/proposals/simple-lambda-parameters-with-modifiers.md": "This proposal allows lambda parameters to be declared with modifiers without requiring their type names. You can add modifiers like `ref` and `out` to lambda parameters without specifying their type.", + "_csharplang/proposals/partial-events-and-constructors.md": "This proposal allows partial events and constructors to be declared in partial classes. The event and constructor can be split across class declarations.", + "_csharplang/proposals/null-conditional-assignment.md": "This proposal allows the null conditional operator to be used for the destination of assignment expressions. This allows you to assign a value to a property or field only if the left side is not null.", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "Learn about any breaking changes since the initial release of C# 10 and included in C# 11", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "Learn about any breaking changes since the initial release of C# 11 and included in C# 12", "_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "Learn about any breaking changes since the initial release of C# 12 and included in C# 13", diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md index d74822119c076..492ae17b18798 100644 --- a/docs/azure/includes/dotnet-all.md +++ b/docs/azure/includes/dotnet-all.md @@ -43,8 +43,8 @@ | Document Translation | NuGet [2.0.0](https://www.nuget.org/packages/Azure.AI.Translation.Document/2.0.0) | [docs](/dotnet/api/overview/azure/AI.Translation.Document-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Translation.Document_2.0.0/sdk/translation/Azure.AI.Translation.Document/) | | Event Grid | NuGet [4.30.0](https://www.nuget.org/packages/Azure.Messaging.EventGrid/4.30.0) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid-readme) | GitHub [4.30.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid_4.30.0/sdk/eventgrid/Azure.Messaging.EventGrid/) | | Event Grid Namespaces | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Messaging.EventGrid.Namespaces/1.0.0) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid.Namespaces-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid.Namespaces_1.0.0/sdk/eventgrid/Azure.Messaging.EventGrid.Namespaces/) | -| Event Hubs | NuGet [5.12.0](https://www.nuget.org/packages/Azure.Messaging.EventHubs/5.12.0) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs-readme) | GitHub [5.12.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs_5.12.0/sdk/eventhub/Azure.Messaging.EventHubs/) | -| Event Hubs - Event Processor | NuGet [5.12.0](https://www.nuget.org/packages/Azure.Messaging.EventHubs.Processor/5.12.0) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs.Processor-readme) | GitHub [5.12.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs.Processor_5.12.0/sdk/eventhub/Azure.Messaging.EventHubs.Processor/) | +| Event Hubs | NuGet [5.12.1](https://www.nuget.org/packages/Azure.Messaging.EventHubs/5.12.1) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs-readme) | GitHub [5.12.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs_5.12.1/sdk/eventhub/Azure.Messaging.EventHubs/) | +| Event Hubs - Event Processor | NuGet [5.12.1](https://www.nuget.org/packages/Azure.Messaging.EventHubs.Processor/5.12.1) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs.Processor-readme) | GitHub [5.12.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs.Processor_5.12.1/sdk/eventhub/Azure.Messaging.EventHubs.Processor/) | | Face | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.AI.Vision.Face/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/AI.Vision.Face-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Vision.Face_1.0.0-beta.2/sdk/face/Azure.AI.Vision.Face/) | | FarmBeats | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.Verticals.AgriFood.Farming/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/Verticals.AgriFood.Farming-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Verticals.AgriFood.Farming_1.0.0-beta.2/sdk/agrifood/Azure.Verticals.AgriFood.Farming/) | | Form Recognizer | NuGet [4.1.0](https://www.nuget.org/packages/Azure.AI.FormRecognizer/4.1.0) | [docs](/dotnet/api/overview/azure/AI.FormRecognizer-readme) | GitHub [4.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.FormRecognizer_4.1.0/sdk/formrecognizer/Azure.AI.FormRecognizer/) | @@ -134,7 +134,7 @@ | Secrets Configuration Provider for .NET | NuGet [1.4.0](https://www.nuget.org/packages/Azure.Extensions.AspNetCore.Configuration.Secrets/1.4.0) | [docs](/dotnet/api/overview/azure/Extensions.AspNetCore.Configuration.Secrets-readme) | GitHub [1.4.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Extensions.AspNetCore.Configuration.Secrets_1.4.0/sdk/extensions/Azure.Extensions.AspNetCore.Configuration.Secrets/) | | Storage - Common | NuGet [12.23.0](https://www.nuget.org/packages/Azure.Storage.Common/12.23.0) | [docs](/dotnet/api/overview/azure/Storage.Common-readme) | GitHub [12.23.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Storage.Common_12.23.0/sdk/storage/Azure.Storage.Common/) | | WebJobs Extensions - Event Grid | NuGet [3.4.4](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventGrid/3.4.4) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.EventGrid-readme) | GitHub [3.4.4](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.EventGrid_3.4.4/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/) | -| WebJobs Extensions - Event Hubs | NuGet [6.5.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventHubs/6.5.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.EventHubs-readme) | GitHub [6.5.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.EventHubs_6.5.0/sdk/eventhub/Microsoft.Azure.WebJobs.Extensions.EventHubs/) | +| WebJobs Extensions - Event Hubs | NuGet [6.5.1](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventHubs/6.5.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.EventHubs-readme) | GitHub [6.5.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.EventHubs_6.5.1/sdk/eventhub/Microsoft.Azure.WebJobs.Extensions.EventHubs/) | | WebJobs Extensions - Service Bus | NuGet [5.16.6](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.ServiceBus/5.16.6) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.ServiceBus-readme) | GitHub [5.16.6](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.ServiceBus_5.16.6/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/) | | WebJobs Extensions - SignalR Service | NuGet [2.0.1](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.SignalRService/2.0.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.SignalRService-readme) | GitHub [2.0.1](https://github.com/Azure/azure-functions-signalrservice-extension/tree/v1.2.0/src/SignalRServiceExtension) | | WebJobs Extensions - Storage | NuGet [5.3.4](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Storage/5.3.4) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.Storage-readme) | GitHub [5.3.4](https://github.com/Azure/azure-webjobs-sdk/tree/master/src/Microsoft.Azure.WebJobs.Extensions.Storage) | @@ -319,7 +319,7 @@ | Resource Management - Quota | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.Quota/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Quota-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Quota_1.1.0/sdk/quota/Azure.ResourceManager.Quota/) | | Resource Management - Recovery Services | NuGet [1.1.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServices/1.1.1)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServices/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServices-readme) | GitHub [1.1.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServices_1.1.1/sdk/recoveryservices/Azure.ResourceManager.RecoveryServices/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServices_1.2.0-beta.1/sdk/recoveryservices/Azure.ResourceManager.RecoveryServices/) | | Resource Management - Recovery Services Backup | NuGet [1.2.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesBackup/1.2.1) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesBackup-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesBackup_1.2.1/sdk/recoveryservices-backup/Azure.ResourceManager.RecoveryServicesBackup/) | -| Resource Management - Recovery Services Data Replication | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesDataReplication/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesDataReplication-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesDataReplication_1.0.0-beta.3/sdk/recoveryservices-datareplication/Azure.ResourceManager.RecoveryServicesDataReplication/) | +| Resource Management - Recovery Services Data Replication | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesDataReplication/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesDataReplication-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesDataReplication_1.0.0/sdk/recoveryservices-datareplication/Azure.ResourceManager.RecoveryServicesDataReplication/) | | Resource Management - Recovery Services Site Recovery | NuGet [1.2.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesSiteRecovery/1.2.1) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesSiteRecovery-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesSiteRecovery_1.2.1/sdk/recoveryservices-siterecovery/Azure.ResourceManager.RecoveryServicesSiteRecovery/) | | Resource Management - Redis | NuGet [1.5.0](https://www.nuget.org/packages/Azure.ResourceManager.Redis/1.5.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Redis-readme) | GitHub [1.5.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Redis_1.5.0/sdk/redis/Azure.ResourceManager.Redis/) | | Resource Management - Redis Enterprise | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.RedisEnterprise/1.1.0)
NuGet [1.2.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.RedisEnterprise/1.2.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.RedisEnterprise-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RedisEnterprise_1.1.0/sdk/redisenterprise/Azure.ResourceManager.RedisEnterprise/)
GitHub [1.2.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RedisEnterprise_1.2.0-beta.2/sdk/redisenterprise/Azure.ResourceManager.RedisEnterprise/) | @@ -375,7 +375,7 @@ | DotNetty | NuGet [0.7.6](https://www.nuget.org/packages/DotNetty.Common/0.7.6) | | | | Functions Extension MCP | NuGet [1.0.0-preview.2](https://www.nuget.org/packages/Microsoft.Azure.Functions.Extensions.Mcp/1.0.0-preview.2) | | | | Functions Worker Extension MCP | NuGet [1.0.0-preview.2](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Mcp/1.0.0-preview.2) | | | -| Functions Worker Extension MySQL | NuGet [1.0.98](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.MySql/1.0.98) | | | +| Functions Worker Extension MySQL | NuGet [1.0.129](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.MySql/1.0.129) | | | | HTTP ASPNETCore Analyzers | NuGet [1.0.3](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers/1.0.3) | | | | IoT Operations MQTT | NuGet [0.10.0](https://www.nuget.org/packages/Azure.Iot.Operations.Mqtt/0.10.0) | | | | IoT Operations Protocol | NuGet [0.10.0](https://www.nuget.org/packages/Azure.Iot.Operations.Protocol/0.10.0) | | | @@ -391,7 +391,7 @@ | Speech Extension ONNX Runtime | NuGet [1.43.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech.Extension.ONNX.Runtime/1.43.0) | | | | Speech Extension Telemetry | NuGet [1.43.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech.Extension.Telemetry/1.43.0) | | | | System Net Client Model | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/System.Net.ClientModel/1.0.0-beta.1) | | | -| WebJobs Extension MySQL | NuGet [1.0.98](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.MySql/1.0.98) | | | +| WebJobs Extension MySQL | NuGet [1.0.129](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.MySql/1.0.129) | | | | Anomaly Detector | NuGet [1.0.0](https://www.nuget.org/packages/Microsoft.Azure.CognitiveServices.AnomalyDetector/1.0.0) | | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.CognitiveServices.AnomalyDetector_1.0.0-preview.1/sdk/cognitiveservices/AnomalyDetector) | | App Service | NuGet [0.2.2-alpha](https://www.nuget.org/packages/Microsoft.Azure.AppService/0.2.2-alpha) | | | | Application Insights | NuGet [0.9.0-preview](https://www.nuget.org/packages/Microsoft.Azure.ApplicationInsights/0.9.0-preview) | | | diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md index d9f4b81558792..6f407cb41a77d 100644 --- a/docs/azure/includes/dotnet-new.md +++ b/docs/azure/includes/dotnet-new.md @@ -44,8 +44,8 @@ | Document Translation | NuGet [2.0.0](https://www.nuget.org/packages/Azure.AI.Translation.Document/2.0.0) | [docs](/dotnet/api/overview/azure/AI.Translation.Document-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Translation.Document_2.0.0/sdk/translation/Azure.AI.Translation.Document/) | | Event Grid | NuGet [4.30.0](https://www.nuget.org/packages/Azure.Messaging.EventGrid/4.30.0) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid-readme) | GitHub [4.30.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid_4.30.0/sdk/eventgrid/Azure.Messaging.EventGrid/) | | Event Grid Namespaces | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Messaging.EventGrid.Namespaces/1.0.0) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid.Namespaces-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid.Namespaces_1.0.0/sdk/eventgrid/Azure.Messaging.EventGrid.Namespaces/) | -| Event Hubs | NuGet [5.12.0](https://www.nuget.org/packages/Azure.Messaging.EventHubs/5.12.0) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs-readme) | GitHub [5.12.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs_5.12.0/sdk/eventhub/Azure.Messaging.EventHubs/) | -| Event Hubs - Event Processor | NuGet [5.12.0](https://www.nuget.org/packages/Azure.Messaging.EventHubs.Processor/5.12.0) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs.Processor-readme) | GitHub [5.12.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs.Processor_5.12.0/sdk/eventhub/Azure.Messaging.EventHubs.Processor/) | +| Event Hubs | NuGet [5.12.1](https://www.nuget.org/packages/Azure.Messaging.EventHubs/5.12.1) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs-readme) | GitHub [5.12.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs_5.12.1/sdk/eventhub/Azure.Messaging.EventHubs/) | +| Event Hubs - Event Processor | NuGet [5.12.1](https://www.nuget.org/packages/Azure.Messaging.EventHubs.Processor/5.12.1) | [docs](/dotnet/api/overview/azure/Messaging.EventHubs.Processor-readme) | GitHub [5.12.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventHubs.Processor_5.12.1/sdk/eventhub/Azure.Messaging.EventHubs.Processor/) | | Face | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.AI.Vision.Face/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/AI.Vision.Face-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Vision.Face_1.0.0-beta.2/sdk/face/Azure.AI.Vision.Face/) | | FarmBeats | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.Verticals.AgriFood.Farming/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/Verticals.AgriFood.Farming-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Verticals.AgriFood.Farming_1.0.0-beta.2/sdk/agrifood/Azure.Verticals.AgriFood.Farming/) | | Form Recognizer | NuGet [4.1.0](https://www.nuget.org/packages/Azure.AI.FormRecognizer/4.1.0) | [docs](/dotnet/api/overview/azure/AI.FormRecognizer-readme) | GitHub [4.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.FormRecognizer_4.1.0/sdk/formrecognizer/Azure.AI.FormRecognizer/) | @@ -139,7 +139,7 @@ | Secrets Configuration Provider for .NET | NuGet [1.4.0](https://www.nuget.org/packages/Azure.Extensions.AspNetCore.Configuration.Secrets/1.4.0) | [docs](/dotnet/api/overview/azure/Extensions.AspNetCore.Configuration.Secrets-readme) | GitHub [1.4.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Extensions.AspNetCore.Configuration.Secrets_1.4.0/sdk/extensions/Azure.Extensions.AspNetCore.Configuration.Secrets/) | | Storage - Common | NuGet [12.23.0](https://www.nuget.org/packages/Azure.Storage.Common/12.23.0) | [docs](/dotnet/api/overview/azure/Storage.Common-readme) | GitHub [12.23.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Storage.Common_12.23.0/sdk/storage/Azure.Storage.Common/) | | WebJobs Extensions - Event Grid | NuGet [3.4.4](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventGrid/3.4.4) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.EventGrid-readme) | GitHub [3.4.4](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.EventGrid_3.4.4/sdk/eventgrid/Microsoft.Azure.WebJobs.Extensions.EventGrid/) | -| WebJobs Extensions - Event Hubs | NuGet [6.5.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventHubs/6.5.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.EventHubs-readme) | GitHub [6.5.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.EventHubs_6.5.0/sdk/eventhub/Microsoft.Azure.WebJobs.Extensions.EventHubs/) | +| WebJobs Extensions - Event Hubs | NuGet [6.5.1](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventHubs/6.5.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.EventHubs-readme) | GitHub [6.5.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.EventHubs_6.5.1/sdk/eventhub/Microsoft.Azure.WebJobs.Extensions.EventHubs/) | | WebJobs Extensions - Service Bus | NuGet [5.16.6](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.ServiceBus/5.16.6) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.ServiceBus-readme) | GitHub [5.16.6](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.ServiceBus_5.16.6/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/) | | WebJobs Extensions - SignalR Service | NuGet [2.0.1](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.SignalRService/2.0.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.SignalRService-readme) | GitHub [2.0.1](https://github.com/Azure/azure-functions-signalrservice-extension/tree/v1.2.0/src/SignalRServiceExtension) | | WebJobs Extensions - Storage | NuGet [5.3.4](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Storage/5.3.4) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.Storage-readme) | GitHub [5.3.4](https://github.com/Azure/azure-webjobs-sdk/tree/master/src/Microsoft.Azure.WebJobs.Extensions.Storage) | @@ -327,7 +327,7 @@ | Resource Management - Quota | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.Quota/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Quota-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Quota_1.1.0/sdk/quota/Azure.ResourceManager.Quota/) | | Resource Management - Recovery Services | NuGet [1.1.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServices/1.1.1)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServices/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServices-readme) | GitHub [1.1.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServices_1.1.1/sdk/recoveryservices/Azure.ResourceManager.RecoveryServices/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServices_1.2.0-beta.1/sdk/recoveryservices/Azure.ResourceManager.RecoveryServices/) | | Resource Management - Recovery Services Backup | NuGet [1.2.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesBackup/1.2.1) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesBackup-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesBackup_1.2.1/sdk/recoveryservices-backup/Azure.ResourceManager.RecoveryServicesBackup/) | -| Resource Management - Recovery Services Data Replication | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesDataReplication/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesDataReplication-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesDataReplication_1.0.0-beta.3/sdk/recoveryservices-datareplication/Azure.ResourceManager.RecoveryServicesDataReplication/) | +| Resource Management - Recovery Services Data Replication | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesDataReplication/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesDataReplication-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesDataReplication_1.0.0/sdk/recoveryservices-datareplication/Azure.ResourceManager.RecoveryServicesDataReplication/) | | Resource Management - Recovery Services Site Recovery | NuGet [1.2.1](https://www.nuget.org/packages/Azure.ResourceManager.RecoveryServicesSiteRecovery/1.2.1) | [docs](/dotnet/api/overview/azure/ResourceManager.RecoveryServicesSiteRecovery-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RecoveryServicesSiteRecovery_1.2.1/sdk/recoveryservices-siterecovery/Azure.ResourceManager.RecoveryServicesSiteRecovery/) | | Resource Management - Redis | NuGet [1.5.0](https://www.nuget.org/packages/Azure.ResourceManager.Redis/1.5.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Redis-readme) | GitHub [1.5.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Redis_1.5.0/sdk/redis/Azure.ResourceManager.Redis/) | | Resource Management - Redis Enterprise | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.RedisEnterprise/1.1.0)
NuGet [1.2.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.RedisEnterprise/1.2.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.RedisEnterprise-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RedisEnterprise_1.1.0/sdk/redisenterprise/Azure.ResourceManager.RedisEnterprise/)
GitHub [1.2.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.RedisEnterprise_1.2.0-beta.2/sdk/redisenterprise/Azure.ResourceManager.RedisEnterprise/) | diff --git a/docs/core/compatibility/core-libraries/10.0/asyncenumerable.md b/docs/core/compatibility/core-libraries/10.0/asyncenumerable.md index c72b3f56fd601..635c39470324c 100644 --- a/docs/core/compatibility/core-libraries/10.0/asyncenumerable.md +++ b/docs/core/compatibility/core-libraries/10.0/asyncenumerable.md @@ -8,7 +8,7 @@ ms.custom: https://github.com/dotnet/docs/issues/44886 # System.Linq.AsyncEnumerable in .NET 10 -.NET 10 introduces the `AsyncEnumerable` class, which provides a full set of LINQ extension methods for the type. This class replaces the community-maintained `System.Linq.Async` NuGet library, potentially causing compilation errors due to ambiguities. +.NET 10 introduces the class, which provides a full set of LINQ extension methods for the type. This class replaces the [community-maintained `System.Linq.Async` NuGet library](https://www.nuget.org/packages/System.Linq.Async), potentially causing compilation errors due to ambiguities. ## Version introduced @@ -16,11 +16,11 @@ ms.custom: https://github.com/dotnet/docs/issues/44886 ## Previous behavior -The `AsyncEnumerable` class in the `System.Linq.Async` package provided LINQ support for . +The `AsyncEnumerable` class in the [community-maintained `System.Linq.Async` package](https://www.nuget.org/packages/System.Linq.Async) provided LINQ support for . ## New behavior -The `AsyncEnumerable` class in .NET 10, as well as in the `System.Linq.AsyncEnumerable` NuGet package, provides LINQ support for . +The class in .NET 10, and in the [`System.Linq.AsyncEnumerable` NuGet package](https://www.nuget.org/packages/System.Linq.AsyncEnumerable/), provides LINQ support for . ## Type of breaking change @@ -28,7 +28,7 @@ This is a [source incompatible](../../categories.md#source-compatibility) change ## Reason for change - has become core enough that the platform itself should provide LINQ support for the type. Community support, including from the maintainers of `System.Linq.Async`, petitioned for this inclusion directly in the platform. + is a commonly used interface, so the platform itself should provide LINQ support for the type. Maintainers of `System.Linq.Async` and other community members petitioned for inclusion directly in the platform. ## Recommended action @@ -42,9 +42,12 @@ If `System.Linq.Async` is consumed indirectly via another package, avoid ambigui ``` -Most consuming code will not need changes, but some call sites might need updates to refer to newer names and signatures. +Most consuming code should be compatible without changes, but some call sites might need updates to refer to newer names and signatures. + +Refer to the [System.Linq.AsyncEnumerable API documentation](xref:System.Linq.AsyncEnumerable) for the full set of LINQ extension methods available for . ## Affected APIs -- `System.Linq.AsyncEnumerable` -- +- +- +- [System.Linq.Async package](https://www.nuget.org/packages/System.Linq.Async) (community-maintained) diff --git a/docs/core/project-sdk/msbuild-props.md b/docs/core/project-sdk/msbuild-props.md index 111bad198a0fa..25c9633fa9ac0 100644 --- a/docs/core/project-sdk/msbuild-props.md +++ b/docs/core/project-sdk/msbuild-props.md @@ -395,9 +395,9 @@ For example, for a .NET 5 app, the output path changes from `bin\Debug\net5.0` t ### AppendRuntimeIdentifierToOutputPath -The `AppendRuntimeIdentifierToOutputPath` property controls whether the [runtime identifier (RID)](../rid-catalog.md) is appended to the output path. The .NET SDK automatically appends the target framework and, if present, the runtime identifier to the output path. Setting `AppendRuntimeIdentifierToOutputPath` to `false` prevents the RID from being appended to the output path. +The `AppendRuntimeIdentifierToOutputPath` property controls whether the [runtime identifier (RID)](../rid-catalog.md) is appended to the output path. The .NET SDK automatically appends the target framework and, if present, the runtime identifier (RID) to the output path. Setting `AppendRuntimeIdentifierToOutputPath` to `false` prevents the RID from being appended to the output path. (However, the RID **is** still appended to the publish path. For more information, see [dotnet/sdk#12114](https://github.com/dotnet/sdk/issues/12114).) -For example, for a .NET 5 app and an RID of `win-x64`, the following setting changes the output path from `bin\Debug\net5.0\win-x64` to `bin\Debug\net5.0`: +For example, for a .NET 9 app and an RID of `win-x64`, the following setting changes the output path from `bin\Debug\net9.0\win-x64` to `bin\Debug\net9.0`: ```xml @@ -1463,34 +1463,24 @@ The allowed values of this property are SDK feature bands, for example, 8.0.100 For more information, see [SDK Analysis Level Property and Usage](https://github.com/dotnet/designs/blob/main/proposed/sdk-analysis-level.md). -## Test project–related properties +## Microsoft.Testing.Platform–related properties The following MSBuild properties are documented in this section: -- [IsTestProject](#istestproject) - [IsTestingPlatformApplication](#istestingplatformapplication) - [Enable\[NugetPackageNameWithoutDots\]](#enablenugetpackagenamewithoutdots) - [EnableAspireTesting](#enableaspiretesting) -- [EnablePlaywright](#enableplaywright) - [EnableMSTestRunner](#enablemstestrunner) - [EnableNUnitRunner](#enablenunitrunner) +- [EnablePlaywright](#enableplaywright) +- [GenerateTestingPlatformConfigurationFile](#generatetestingplatformconfigurationfile) - [GenerateTestingPlatformEntryPoint](#generatetestingplatformentrypoint) +- [TestingExtensionsProfile](#testingextensionsprofile) - [TestingPlatformCaptureOutput](#testingplatformcaptureoutput) - [TestingPlatformCommandLineArguments](#testingplatformcommandlinearguments) - [TestingPlatformDotnetTestSupport](#testingplatformdotnettestsupport) - [TestingPlatformShowTestsFailure](#testingplatformshowtestsfailure) -- [TestingExtensionsProfile](#testingextensionsprofile) -- [UseVSTest](#usevstest) -- [MSTestAnalysisMode](#mstestanalysismode) - -### IsTestProject - -The `IsTestProject` property signifies that a project is a test project. When this property is set to `true`, validation to check if the project references a self-contained executable is disabled. That's because test projects have an `OutputType` of `Exe` but usually call APIs in a referenced executable rather than trying to run. In addition, if a project references a project where `IsTestProject` is set to `true`, the test project isn't validated as an executable reference. - -This property is mainly needed for the `dotnet test` scenario and has no impact when using *vstest.console.exe*. - -> [!NOTE] -> If your project specifies the [MSTest SDK](../testing/unit-testing-mstest-sdk.md), you don't need to set this property. It's set automatically. Similarly, this property is set automatically for projects that reference the Microsoft.NET.Test.Sdk NuGet package linked to VSTest. +- [UseMicrosoftTestingPlatformRunner](#usemicrosofttestingplatformrunner) ### IsTestingPlatformApplication @@ -1535,6 +1525,10 @@ The `EnableMSTestRunner` property enables or disables the use of the [MSTest run The `EnableNUnitRunner` property enables or disables the use of the [NUnit runner](../testing/unit-testing-nunit-runner-intro.md). The NUnit runner is a lightweight and portable alternative to VSTest. This property is available in [NUnit3TestAdapter](https://www.nuget.org/packages/NUnit3TestAdapter) in version 5.0 and later. +## UseMicrosoftTestingPlatformRunner + +The `UseMicrosoftTestingPlatformRunner` property enables or disables the use of Microsoft.Testing.Platform runner in [xUnit.v3](https://xunit.net) test projects. + ### GenerateTestingPlatformEntryPoint Setting the `GenerateTestingPlatformEntryPoint` property to `false` disables the automatic generation of the program entry point in test projects that use [Microsoft.Testing.Platform](../testing/microsoft-testing-platform-intro.md). You might want to set this property to `false` when you manually define an entry point, or when you reference a test project from an executable that also has an entry point. @@ -1543,6 +1537,10 @@ For more information, see [error CS8892](../testing/microsoft-testing-platform-f To control the generation of the entry point in a VSTest project, use the `GenerateProgramFile` property. +### GenerateTestingPlatformConfigurationFile + +The `GenerateTestingPlatformConfigurationFile` property is only available when [IsTestingPlatformApplication](#istestingplatformapplication) is `true`. It's used to allow the copy and rename of the [config file](../testing/microsoft-testing-platform-config.md) in the output folder. + ### TestingPlatformCaptureOutput The `TestingPlatformCaptureOutput` property controls whether all console output that a test executable writes is captured and hidden from the user when you use `dotnet test` to run `Microsoft.Testing.Platform` tests. By default, the console output is hidden. This output includes the banner, version information, and formatted test information. Set this property to `false` to show this information together with MSBuild output. @@ -1562,9 +1560,12 @@ The `TestingPlatformCaptureOutput` property lets you specify command-line argume ### TestingPlatformDotnetTestSupport -The `TestingPlatformDotnetTestSupport` property lets you specify whether VSTest is used when you use `dotnet test` to run tests. If you set this property to `true`, VSTest is disabled and all `Microsoft.Testing.Platform` tests are run directly. +The `TestingPlatformDotnetTestSupport` property enables testing Microsoft.Testing.Platform apps when using the VSTest mode of `dotnet test`. -If you have a solution that contains VSTest test projects as well as MSTest, NUnit, or XUnit projects, you should make one call per mode (that is, `dotnet test` won't run tests from both VSTest and the newer platforms in one call). +> [!NOTE] +> Don't call `dotnet test` on a solution that has both VSTest and Microsoft.Testing.Platform projects, as that scenario is not supported. + +For more information, see [Testing with 'dotnet test'](../testing/unit-testing-with-dotnet-test.md). ### TestingPlatformShowTestsFailure @@ -1582,10 +1583,30 @@ When you use the [MSTest project SDK](../testing/unit-testing-mstest-sdk.md), th For more information, see [Microsoft.Testing.Platform profile](../testing/unit-testing-mstest-sdk.md#microsofttestingplatform-profile). +## VSTest–related properties + +The following MSBuild properties are documented in this section: + +- [IsTestProject](#istestproject) +- [UseVSTest](#usevstest) + +### IsTestProject + +The `IsTestProject` property is set to `true` by the [Microsoft.NET.Test.Sdk NuGet package](https://www.nuget.org/packages/Microsoft.NET.Test.Sdk). It signifies whether a project is a VSTest test project so that it's recognized by `dotnet test`. + +> [!NOTE] +> If your project specifies the [MSTest SDK](../testing/unit-testing-mstest-sdk.md), you don't need to set this property, as MSTest.Sdk references the Microsoft.NET.Test.Sdk NuGet package. + ### UseVSTest Set the `UseVSTest` property to `true` to switch from Microsoft.Testing.Platform to the [VSTest](/visualstudio/test/vstest-console-options) runner when using the [MSTest project SDK](../testing/unit-testing-mstest-sdk.md). +## MSTest–related properties + +The following MSBuild properties are documented in this section: + +- [MSTestAnalysisMode](#mstestanalysismode) + ### MSTestAnalysisMode This property decides which analyzers are enabled at which severity. For more information, see [MSTest code analysis](../testing/mstest-analyzers/overview.md). diff --git a/docs/core/testing/unit-testing-csharp-with-xunit.md b/docs/core/testing/unit-testing-csharp-with-xunit.md index b58ec4df2cb2b..2be26dd9d0082 100644 --- a/docs/core/testing/unit-testing-csharp-with-xunit.md +++ b/docs/core/testing/unit-testing-csharp-with-xunit.md @@ -7,7 +7,7 @@ ms.date: 03/07/2024 --- # Unit testing C# in .NET using dotnet test and xUnit -This tutorial shows how to build a solution containing a unit test project and source code project. To follow the tutorial using a pre-built solution, [view or download the sample code](https://github.com/dotnet/samples/tree/main/core/getting-started/unit-testing-using-dotnet-test/). For download instructions, see [Samples and Tutorials](../../samples-and-tutorials/index.md#view-and-download-samples). +This tutorial shows how to build a solution containing a unit test project and source code project. To follow the tutorial using a prebuilt solution, [view or download the sample code](https://github.com/dotnet/samples/tree/main/core/getting-started/unit-testing-using-dotnet-test/). For download instructions, see [Samples and Tutorials](../../samples-and-tutorials/index.md#view-and-download-samples). ## Create the solution @@ -60,11 +60,7 @@ The following instructions provide the steps to create the test solution. See [C } ``` -* The preceding code: - * Throws a with a message indicating it's not implemented. - * Is updated later in the tutorial. - - + Currently this code throws a , but you'll implement the method later in the tutorial. * In the *unit-testing-using-dotnet-test* directory, run the following command to add the class library project to the solution: @@ -78,13 +74,12 @@ The following instructions provide the steps to create the test solution. See [C dotnet new xunit -o PrimeService.Tests ``` -* The preceding command: - * Creates the *PrimeService.Tests* project in the *PrimeService.Tests* directory. The test project uses [xUnit](https://xunit.net/) as the test library. - * Configures the test runner by adding the following ``elements to the project file: - * `Microsoft.NET.Test.Sdk` - * `xunit` - * `xunit.runner.visualstudio` - * `coverlet.collector` + The preceding command creates the *PrimeService.Tests* project in the *PrimeService.Tests* directory. The test project uses [xUnit](https://xunit.net/) as the test library. The command also configures the test runner by adding the following ``elements to the project file: + + * `Microsoft.NET.Test.Sdk` + * `xunit` + * `xunit.runner.visualstudio` + * `coverlet.collector` * Add the test project to the solution file by running the following command: @@ -121,7 +116,7 @@ Follow the instructions for "Replace the code in *PrimeService.cs* with the foll ## Create a test -A popular approach in test driven development (TDD) is to write a (failing) test before implementing the target code. This tutorial uses the TDD approach. The `IsPrime` method is callable, but not implemented. A test call to `IsPrime` fails. With TDD, a test is written that is known to fail. The target code is updated to make the test pass. You keep repeating this approach, writing a failing test and then updating the target code to pass. +A popular approach in test driven development (TDD) is to write a (failing) test before implementing the target code. This tutorial uses the TDD approach. The `IsPrime` method is callable but not implemented. A test call to `IsPrime` fails. With TDD, you write a test that's known to fail. Then you update the target code to make the test pass. You keep repeating this approach, writing a failing test and then updating the target code to pass. Update the *PrimeService.Tests* project: @@ -129,25 +124,25 @@ Update the *PrimeService.Tests* project: * Create a *PrimeService.Tests/PrimeService_IsPrimeShould.cs* file. * Replace the code in *PrimeService_IsPrimeShould.cs* with the following code: -```csharp -using Xunit; -using Prime.Services; + ```csharp + using Xunit; + using Prime.Services; -namespace Prime.UnitTests.Services -{ - public class PrimeService_IsPrimeShould - { - [Fact] - public void IsPrime_InputIs1_ReturnFalse() - { - var primeService = new PrimeService(); - bool result = primeService.IsPrime(1); - - Assert.False(result, "1 should not be prime"); - } - } -} -``` + namespace Prime.UnitTests.Services + { + public class PrimeService_IsPrimeShould + { + [Fact] + public void IsPrime_InputIs1_ReturnFalse() + { + var primeService = new PrimeService(); + bool result = primeService.IsPrime(1); + + Assert.False(result, "1 should not be prime"); + } + } + } + ``` The `[Fact]` attribute declares a test method that's run by the test runner. From the *PrimeService.Tests* folder, run `dotnet test`. The [dotnet test](../tools/dotnet-test.md) command builds both projects and runs the tests. The xUnit test runner contains the program entry point to run the tests. `dotnet test` starts the test runner using the unit test project. @@ -168,8 +163,7 @@ Run `dotnet test`. The test passes. ### Add more tests -Add prime number tests for 0 and -1. You could copy the test created in the preceding step and make copies of the following code to test 0 and -1. -But don't do it, as there's a better way. +Add prime number tests for 0 and -1. You *could* copy the test created in the preceding step and make copies of the following code to test 0 and -1. But don't do it, as there's a better way. ```csharp var primeService = new PrimeService(); @@ -180,10 +174,10 @@ Assert.False(result, "1 should not 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: -- `[Theory]` represents a suite of tests that execute the same code but have different input arguments. -- `[InlineData]` attribute specifies values for those inputs. +* `[Theory]` represents a suite of tests that execute the same code but have different input arguments. +* `[InlineData]` attribute specifies values for those inputs. -Rather than creating new tests, apply the preceding xUnit attributes to create a single theory. Replace the following code: +Rather than creating new tests, apply the preceding xUnit attributes to create a single theory. Replace the following code... ```csharp [Fact] @@ -196,15 +190,15 @@ public void IsPrime_InputIs1_ReturnFalse() } ``` -with the following code: +...with the following code: - :::code language="csharp" source="../../../samples/snippets/core/testing/unit-testing-using-dotnet-test/csharp/PrimeService.Tests/PrimeService_IsPrimeShould.cs" id="Sample_TestCode"::: +:::code language="csharp" source="../../../samples/snippets/core/testing/unit-testing-using-dotnet-test/csharp/PrimeService.Tests/PrimeService_IsPrimeShould.cs" id="Sample_TestCode"::: In the preceding code, `[Theory]` and `[InlineData]` enable testing several values less than two. Two is the smallest prime number. Add the following code after the class declaration and before the `[Theory]` attribute: - :::code language="csharp" source="../../../samples/snippets/core/testing/unit-testing-using-dotnet-test/csharp/PrimeService.Tests/PrimeService_IsPrimeShould.cs" id="Sample_InitCode"::: +:::code language="csharp" source="../../../samples/snippets/core/testing/unit-testing-using-dotnet-test/csharp/PrimeService.Tests/PrimeService_IsPrimeShould.cs" id="Sample_InitCode"::: Run `dotnet test`, and two of the tests fail. To make all of the tests pass, update the `IsPrime` method with the following code: @@ -225,6 +219,6 @@ The completed `IsPrime` method is not an efficient algorithm for testing primali ### Additional resources -- [xUnit.net official site](https://xunit.net) -- [Testing controller logic in ASP.NET Core](/aspnet/core/mvc/controllers/testing) -- [`dotnet reference add`](../tools/dotnet-reference-add.md) +* [xUnit.net official site](https://xunit.net) +* [Testing controller logic in ASP.NET Core](/aspnet/core/mvc/controllers/testing) +* [`dotnet reference add`](../tools/dotnet-reference-add.md) diff --git a/docs/core/testing/unit-testing-mstest-sdk.md b/docs/core/testing/unit-testing-mstest-sdk.md index 61c589e4f5737..fae458543daa1 100644 --- a/docs/core/testing/unit-testing-mstest-sdk.md +++ b/docs/core/testing/unit-testing-mstest-sdk.md @@ -89,7 +89,7 @@ You can set the profile using the property `TestingExtensionsProfile` with one o * [Code Coverage](./microsoft-testing-platform-extensions-code-coverage.md#microsoft-code-coverage) * [Trx Report](./microsoft-testing-platform-extensions-test-reports.md#visual-studio-test-reports) - + * `AllMicrosoft` - Enable all extensions shipped by Microsoft (including extensions with a restrictive license). Enables the following extensions: @@ -105,7 +105,7 @@ You can set the profile using the property `TestingExtensionsProfile` with one o * [Hot Reload](./microsoft-testing-platform-extensions-hosting.md#hot-reload) * [Retry](./microsoft-testing-platform-extensions-policy.md#retry) - + * [Trx Report](./microsoft-testing-platform-extensions-test-reports.md#visual-studio-test-reports) Here's a full example, using the `None` profile: @@ -285,4 +285,5 @@ The NuGet-provided MSBuild SDKs (including MSTest.Sdk) have limited tooling supp ## See also -- [Test project–related properties](../project-sdk/msbuild-props.md#test-projectrelated-properties) +- [Microsoft.Testing.Platform–related properties](../project-sdk/msbuild-props.md#microsofttestingplatformrelated-properties) +- [VSTest–related properties](../project-sdk/msbuild-props.md#vstestrelated-properties) diff --git a/docs/core/whats-new/dotnet-10/libraries.md b/docs/core/whats-new/dotnet-10/libraries.md index 5a3abb38f47f1..64caded4330dc 100644 --- a/docs/core/whats-new/dotnet-10/libraries.md +++ b/docs/core/whats-new/dotnet-10/libraries.md @@ -2,14 +2,14 @@ title: What's new in .NET libraries for .NET 10 description: Learn about the new .NET libraries features introduced in .NET 10. titleSuffix: "" -ms.date: 03/18/2025 +ms.date: 04/09/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in .NET libraries for .NET 10 -This article describes new features in the .NET libraries for .NET 10. It's updated for Preview 2. +This article describes new features in the .NET libraries for .NET 10. It's updated for Preview 3. ## Find certificates by thumbprints other than SHA-1 @@ -133,7 +133,7 @@ When you use source generators for JSON serialization, the generated context thr ## More left-handed matrix transformation methods -.NET 10 adds the remaining APIs for creating left-handed transformation matrices for billboard and constrained-billboard matrices. You can use these methods like their existing right-handed counterparts [add xrefs to the existing counterparts] when using a left-handed coordinate system instead. +.NET 10 adds the remaining APIs for creating left-handed transformation matrices for billboard and constrained-billboard matrices. You can use these methods like their existing right-handed counterparts and when using a left-handed coordinate system instead. ```csharp public partial struct Matrix4x4 @@ -150,3 +150,68 @@ The new `ExportPkcs12` methods on indicates that AES should be used instead of 3DES (and SHA-2-256 instead of SHA-1), but the output may not be understood by all readers (such as Windows XP). Callers who want even more control can instead utilize the overload that accepts a . + +## New AOT-safe constructor for `ValidationContext` + +The class, used during options validation, now includes a new constructor that explicitly accepts the `displayName` parameter. This ensures AOT safety, allowing its use in native builds without warnings: + +```csharp +public sealed class ValidationContext +{ + public ValidationContext(object instance, + string displayName, + IServiceProvider? serviceProvider = null, + IDictionary? items = null); +} +``` + +## Support for telemetry schema URLs in `ActivitySource` and `Meter` + + and now support specifying a telemetry schema URL during construction, aligning with OpenTelemetry specifications. This ensures consistency and compatibility for tracing and metrics data. Additionally, the update introduces `ActivitySourceOptions`, simplifying the creation of instances with multiple configuration options. + +```csharp +public sealed partial class ActivitySource +{ + public ActivitySource(ActivitySourceOptions options); + public string? TelemetrySchemaUrl { get; } +} + +public class ActivitySourceOptions +{ + public ActivitySourceOptions(string name); + public string Name { get; set; } + public string? Version { get; set; } + public IEnumerable>? Tags { get; set; } + public string? TelemetrySchemaUrl { get; set; } +} + +public partial class Meter : IDisposable +{ + public string? TelemetrySchemaUrl { get; } +} +``` + +## Byte-level support in BPE tokenizer + +The now supports byte-level encoding, enabling compatibility with models like DeepSeek. This enhancement processes vocabulary as UTF-8 bytes. In addition, the new `BpeOptions` type simplifies tokenizer configuration. + +```csharp +BpeOptions bpeOptions = new BpeOptions(vocabs); +BpeTokenizer tokenizer = BpeTokenizer.Create(bpeOptions); +``` + +## Deterministic option for LightGBM trainer in ML.NET + +LightGBM trainers now expose options for deterministic training, ensuring consistent results with the same data and random seed. These options include `deterministic`, `force_row_wise`, and `force_col_wise`. + +```csharp +LightGbmBinaryTrainer trainer = ML.BinaryClassification.Trainers.LightGbm(new LightGbmBinaryTrainer.Options +{ + Deterministic = true, + ForceRowWise = true +}); +``` + +## Tensor enhancements + +The class now includes a nongeneric interface for operations like accessing `Lengths` and `Strides`. Slice operations no longer copy data, improving performance. Additionally, data can be accessed nongenerically by boxing to `object` when performance isn't critical. diff --git a/docs/core/whats-new/dotnet-10/overview.md b/docs/core/whats-new/dotnet-10/overview.md index 951b272782ffd..702067de1d63d 100644 --- a/docs/core/whats-new/dotnet-10/overview.md +++ b/docs/core/whats-new/dotnet-10/overview.md @@ -2,14 +2,14 @@ title: What's new in .NET 10 description: Learn about the new features introduced in .NET 10 for the runtime, libraries, and SDK. Also find links to what's new in other areas, such as ASP.NET Core. titleSuffix: "" -ms.date: 03/18/2025 +ms.date: 04/09/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in .NET 10 -Learn about the new features in .NET 10 and find links to further documentation. This page is updated for Preview 2. +Learn about the new features in .NET 10 and find links to further documentation. This page is updated for Preview 3. .NET 10, the successor to [.NET 9](../dotnet-9/overview.md), is [supported for three years](https://dotnet.microsoft.com/platform/support/policy/dotnet-core) as a long-term support (LTS) release. You can [download .NET 10 here](https://get.dot.net/10). @@ -60,37 +60,13 @@ For more information, see [What's new in the SDK for .NET 10](sdk.md). .NET Aspire releases version 9.1, which focuses on quality-of-life fixes. -For more information, see [What's new in .NET Aspire 9.1](/dotnet/aspire/whats-new/dotnet-aspire-9.1). +For details, see [What's new in .NET Aspire 9.1](/dotnet/aspire/whats-new/dotnet-aspire-9.1). ## ASP.NET Core -The ASP.NET Core 10.0 release introduces several new features and enhancements, including: +The ASP.NET Core 10.0 release introduces several new features and enhancements, including Blazor improvements, OpenAPI enhancements, and minimal API updates. -- **Blazor enhancements**: - - Added the `ReconnectModal` component to the Blazor Web App project template for improved reconnection UI control. - - The `NavigateTo` method no longer scrolls to the top for same-page navigation. - - The `NavLink` component now ignores query strings and fragments when using `NavLinkMatch.All`. - - Added the `RowClass` parameter to `QuickGrid` for applying styles to rows based on their data. - - Added the `CloseColumnOptionsAsync` method to `QuickGrid` for programmatically closing column options. - - Blazor framework script is now served as a static web asset with precompression and fingerprinting enabled. - -- **OpenAPI improvements**: - - Added support for generating OpenAPI version 3.1 documents. - - Added support for serving OpenAPI documents in YAML format. - - Populated XML doc comments into OpenAPI documents. - -- **Minimal APIs**: - - Improved integration testing for apps using top-level statements. - - Empty strings in form posts are now treated as `null` for nullable value types. - -- **Authentication and authorization**: - - Added new metrics for authentication and authorization events. - -- **Miscellaneous**: - - Added the `RedirectHttpResult.IsLocalUrl` helper method for detecting local URLs. - - Added support for route syntax highlighting in the . - -For more information, see [What's new in ASP.NET Core for .NET 10](/aspnet/core/release-notes/aspnetcore-10.0). +For details, see [What's new in ASP.NET Core for .NET 10](/aspnet/core/release-notes/aspnetcore-10.0). ## C# 14 @@ -102,63 +78,11 @@ C# 14 introduces several new features and enhancements to improve developer prod - **Modifiers on simple lambda parameters**: Allows parameter modifiers like `ref`, `in`, or `out` in lambda expressions without specifying parameter types. - **Experimental feature - String literals in data section**: Enables emitting string literals as UTF-8 data into a separate section of the PE file, improving efficiency for certain scenarios. - **Partial events and constructors**: Adds support for partial instance constructors and partial events, complementing partial methods and properties introduced in C# 13. +- **Extension members**: Extension methods now support static methods, instance properties, and static properties through `extension` blocks, enabling more flexible and powerful extensions. +- **Null-conditional assignment**: Simplifies conditional assignments by allowing properties or fields to be updated only if the containing instance exists, using the `?.` operator. For more information, see [What's new in C# 14](../../../csharp/whats-new/csharp-14.md). -## .NET MAUI - -The .NET MAUI updates in .NET 10 include several new features and quality improvements for .NET MAUI, .NET for Android, and .NET for iOS, Mac Catalyst, macOS, and tvOS. Key updates include: - -- **General improvements**: - - New `ShadowTypeConverter` for converting formatted strings to `Shadow` on `VisualElement`. - - Added `SpeechOptions.Rate` for controlling the playback rate in Text-to-Speech. - - Support for styling modals as popovers on iOS and Mac Catalyst. - - Added `Switch.OffColor` for customizing the color of the `Switch` control when off. - - Added `SearchBar.SearchIconColor` for customizing the search icon color. - - New `HybridWebView.InvokeJavascriptAsync` method for invoking JavaScript without requiring generic arguments. - -- **Deprecations**: - - The `FontImageExtension` XAML markup extension is deprecated. Use `FontImageSource` instead. - - `MessagingCenter` is now internal. Replace it with `WeakReferenceMessenger` from the `CommunityToolkit.Mvvm` package. - -- **.NET for Android**: - - Support for Android 16 (API-36) Beta 1. - - Updated recommended minimum supported Android API to 24 (Nougat). - - Support for building with JDK-21. - - Added support for `dotnet run` for Android projects. - - Enabled marshal methods by default for improved startup performance. - - Design-time builds no longer invoke `aapt2`, reducing build times. - -- **.NET for iOS, Mac Catalyst, macOS, tvOS**: - - Trimmer warnings are now enabled by default. - - Bundling of original resources in libraries is now opt-out. - -For more information, see [What's new in .NET MAUI in .NET 10](/dotnet/maui/whats-new/dotnet-10). - -## EF Core - -The EF Core 10 release introduces several new features and improvements, including: - -- **LINQ enhancements**: - - Added support for the `LeftJoin` operator, simplifying LINQ queries that require `LEFT JOIN` operations. - - Added support for the `RightJoin` operator, enabling LINQ queries that require `RIGHT JOIN` operations. - -- **ExecuteUpdateAsync improvements**: - - `ExecuteUpdateAsync` now accepts a regular, non-expression lambda, reducing verbosity when updating entities. - -- **Performance optimizations**: - - Improved translation for `DateOnly.ToDateTime(timeOnly)`. - - Optimized multiple consecutive `LIMIT` operations. - - Enhanced performance for `Count` operations on `ICollection`. - - Optimized `MIN`/`MAX` operations over `DISTINCT`. - -- **Miscellaneous**: - - Simplified parameter names in SQL queries (for example, from `@__city_0` to `city`). - - Added translation for date/time functions using `DatePart.Microsecond` and `DatePart.Nanosecond`. - - Made SQL Server scaffolding compatible with Azure Data Explorer. - -For more information, see [What's new in EF Core for .NET 10](/ef/core/what-is-new/ef-core-10.0/whatsnew). - ## F\# The F# updates in .NET 10 include several new features and improvements across the language, standard library, and compiler service. Key updates include: @@ -185,45 +109,26 @@ These updates ensure that Visual Basic can consume updated features in C# and th For more information, see [What's new in Visual Basic](../../../visual-basic/whats-new/index.md). -## Windows Forms +## .NET MAUI -Changes in Windows Forms for .NET 10 include: +The .NET MAUI updates in .NET 10 include several new features and quality improvements for .NET MAUI, .NET for Android, and .NET for iOS, Mac Catalyst, macOS, and tvOS. -- **Clipboard-related updates**: - - Introduced new APIs for JSON serialization and type-safe data retrieval from the Clipboard, such as `SetDataAsJson` and `TryGetData`. - - Marked several Clipboard-related APIs as obsolete to warn developers about potential `BinaryFormatter` usage. - - Added a configuration switch (`Windows.ClipboardDragDrop.EnableUnsafeBinaryFormatterSerialization`) to explicitly enable `BinaryFormatter` for Clipboard scenarios. - - Unified Clipboard code with WPF to enhance consistency and reliability. +For details, see [What's new in .NET MAUI in .NET 10](/dotnet/maui/whats-new/dotnet-10). -- **Ported UITypeEditors**: - - Ported several `UITypeEditors` from .NET Framework, including `ToolStripCollectionEditor` and editors related to the `DataGridView` control. +## EF Core -- **Quality enhancements**: - - Expanded unit test coverage and addressed various bug fixes to improve stability and performance. +The EF Core 10 release introduces several new features and improvements, including LINQ enhancements, performance optimizations, and improved support for Azure Cosmos DB. -For more information, see [What's new in Windows Forms for .NET 10](/dotnet/desktop/winforms/whats-new/net100). +For details, see [What's new in EF Core for .NET 10](/ef/core/what-is-new/ef-core-10.0/whatsnew). -## WPF - -The WPF updates in .NET 10 include several performance improvements, Fluent style changes, bug fixes, and engineering health updates: +## Windows Forms -- **Performance improvements**: - - Replaced data structures like `PartialList` with `ReadOnlyCollection` to enhance performance. - - Optimized UI automation and file dialog operations to minimize allocations. - - Improved pixel format conversion performance. +Changes in Windows Forms for .NET 10 include clipboard-related updates, ported `UITypeEditors` from .NET Framework, and quality enhancements. -- **Fluent style changes**: - - Updated the default style for `Label`. - - Fixed animation issues for `Expander` by adjusting a `KeyTime` value. +For details, see [What's new in Windows Forms for .NET 10](/dotnet/desktop/winforms/whats-new/net100). -- **Bug fixes**: - - Resolved issues with UI element cursor types and crashes when bitmap streams are null. - - Fixed localization issues for `ScrollViewer` and `ContextMenu`. - - Addressed minor bugs in `BitmapMetadata` and native dependencies. +## WPF -- **Engineering health**: - - Updated and synchronized **MilCodeGen** across WPF components. - - Removed deprecated .NET runtime references and unnecessary package dependencies. - - Conducted style cleanups and disabled code analysis for generated code to streamline builds. +The WPF updates in .NET 10 include several performance improvements, Fluent style changes, bug fixes, and more. -For more information, see [What's new in WPF in .NET 10](/dotnet/desktop/wpf/whats-new/net100). +For details, see [What's new in WPF in .NET 10](/dotnet/desktop/wpf/whats-new/net100). diff --git a/docs/core/whats-new/dotnet-10/runtime.md b/docs/core/whats-new/dotnet-10/runtime.md index be86518225750..a34c62ddfc844 100644 --- a/docs/core/whats-new/dotnet-10/runtime.md +++ b/docs/core/whats-new/dotnet-10/runtime.md @@ -2,13 +2,13 @@ title: What's new in .NET 10 runtime description: Learn about the new .NET features introduced in the .NET 10 runtime. titleSuffix: "" -ms.date: 03/18/2025 +ms.date: 04/09/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in the .NET 10 runtime -This article describes new features and performance improvements in the .NET runtime for .NET 10. It's updated for Preview 2. +This article describes new features and performance improvements in the .NET runtime for .NET 10. It's updated for Preview 3. ## Array interface method devirtualization @@ -60,9 +60,9 @@ The JIT can now inline methods that become eligible for devirtualization due to During inlining, the JIT now updates the type of temporary variables holding return values. If all return sites in a callee yield the same type, this precise type information is used to devirtualize subsequent calls. This enhancement complements the improvements in late devirtualization and array enumeration de-abstraction. For more information, see [dotnet/runtime #111948](https://github.com/dotnet/runtime/pull/111948). -## Stack allocation of arrays of value types +## Stack allocation of small arrays of value types -In .NET 9, the JIT gained the ability to allocate objects on the stack, when the object is guaranteed to not outlive its parent method. Not only does stack allocation reduce the number of objects the GC has to track, but it also unlocks other optimizations. For example, after an object is stack-allocated, the JIT can consider replacing it entirely with its scalar values. Because of this, stack allocation is key to reducing the abstraction penalty of reference types. +In .NET 9, the JIT gained the ability to allocate objects on the stack when the object is guaranteed to not outlive its parent method. Not only does stack allocation reduce the number of objects the GC has to track, but it also unlocks other optimizations. For example, after an object is stack-allocated, the JIT can consider replacing it entirely with its scalar values. Because of this, stack allocation is key to reducing the abstraction penalty of reference types. In .NET 10, the JIT now stack-allocates small, fixed-sized arrays of value types that don't contain GC pointers when it can make the same lifetime guarantees described previously. Consider the following example: @@ -83,6 +83,29 @@ static void Sum() Because the JIT knows `numbers` is an array of only three integers at compile time, and it doesn't outlive a call to `Sum`, it allocates it on the stack. +## Stack allocation of small arrays of reference types + +Building on the stack allocation improvements introduced in .NET 9, .NET 10 extends this optimization to small arrays of reference types. Previously, arrays of reference types were always allocated on the heap, even when their lifetime was scoped to a single method. Now, the JIT can stack-allocate such arrays when it determines that they don't outlive their creation context. For example: + +```csharp +static void Print() +{ + string[] words = {"Hello", "World!"}; + foreach (var str in words) + { + Console.WriteLine(str); + } +} +``` + +In this example, the array `words` is now allocated on the stack, eliminating heap allocations entirely. This reduces GC pressure and improves performance. + +## Improved code layout + +The JIT compiler in .NET 10 introduces a new approach to organizing method code into basic blocks for better runtime performance. Previously, the JIT used a reverse postorder (RPO) traversal of the program's flowgraph as an initial layout, followed by iterative transformations. While effective, this approach had limitations in modeling the trade-offs between reducing branching and increasing hot code density. + +In .NET 10, the JIT models the block reordering problem as a reduction of the asymmetric Travelling Salesman Problem and implements the 3-opt heuristic to find a near-optimal traversal. This optimization improves hot path density and reduces branch distances, resulting in better runtime performance. For more details, see [dotnet/runtime #107749](https://github.com/dotnet/runtime/issues/107749). + ## AVX10.2 support .NET 10 introduces support for the Advanced Vector Extensions (AVX) 10.2 for x64-based processors. The new intrinsics available in the class can be tested once capable hardware is available. diff --git a/docs/core/whats-new/dotnet-10/sdk.md b/docs/core/whats-new/dotnet-10/sdk.md index 1a0b14fdfb6b5..e24c99da06814 100644 --- a/docs/core/whats-new/dotnet-10/sdk.md +++ b/docs/core/whats-new/dotnet-10/sdk.md @@ -2,19 +2,14 @@ title: What's new in the SDK and tooling for .NET 10 description: Learn about the new .NET SDK features introduced in .NET 10. titleSuffix: "" -ms.date: 03/18/2025 +ms.date: 04/09/2025 ms.topic: whats-new ai-usage: ai-assisted --- # What's new in the SDK and tooling for .NET 10 -This article describes new features and enhancements in the .NET SDK for .NET 10. It's updated for Preview 2. - -## New features and enhancements - -- [Pruning of framework-provided package references](#pruning-of-framework-provided-package-references) -- [More consistent command order](#more-consistent-command-order) +This article describes new features and enhancements in the .NET SDK for .NET 10. It's updated for Preview 3. ## Pruning of framework-provided package references @@ -38,3 +33,37 @@ Starting in .NET 10, the `dotnet` CLI tool includes new aliases for common comma | [`dotnet reference remove`](../../tools/dotnet-reference-remove.md) | `dotnet remove reference` | The new noun-first forms align with general CLI standards, making the `dotnet` CLI more consistent with other tools. While the verb-first forms continue to work, it's better to use the noun-first forms for improved readability and consistency in scripts and documentation. + +## CLI commands default to interactive mode in interactive terminals + +The `--interactive` flag is now enabled by default for CLI commands in interactive terminals. This change allows commands to dynamically retrieve credentials or perform other interactive behaviors without requiring the flag to be explicitly set. For noninteractive scenarios, you can disable interactivity by specifying `--interactive false`. + +## Native shell tab-completion scripts + +The `dotnet` CLI now supports generating native tab-completion scripts for popular shells using the `dotnet completions generate [SHELL]` command. Supported shells include `bash`, `fish`, `nushell`, `powershell`, and `zsh`. These scripts improve usability by providing faster and more integrated tab-completion features. For example, in PowerShell, you can enable completions by adding the following to your `$PROFILE`: + +```powershell +dotnet completions script pwsh | out-String | Invoke-Expression -ErrorAction SilentlyContinue +``` + +## Console apps can natively create container images + +Console apps can now create container images via `dotnet publish /t:PublishContainer` without requiring the `` property in the project file. This aligns console apps with the behavior of ASP.NET Core and Worker SDK apps. + +## Explicitly control the image format of containers + +A new `` property allows you to explicitly set the format of container images to either `Docker` or `OCI`. This property overrides the default behavior, which depends on the base image format and whether the container is multi-architecture. + +## Support for Microsoft Testing Platform in `dotnet test` + +Starting in .NET 10, `dotnet test` natively supports the [Microsoft.Testing.Platform](../../testing/microsoft-testing-platform-intro.md). To enable this feature, add the following configuration to your *dotnet.config* file: + +```ini +[dotnet.test:runner] +name = "Microsoft.Testing.Platform" +``` + +> [!NOTE] +> The `[dotnet.test:runner]` part will change to `[dotnet.test.runner]` in Preview 4. + +For more details, see [Testing with `dotnet test`](../../testing/unit-testing-with-dotnet-test.md). diff --git a/docs/csharp/language-reference/operators/assignment-operator.md b/docs/csharp/language-reference/operators/assignment-operator.md index 00a7bef2ef884..86471b7b47e28 100644 --- a/docs/csharp/language-reference/operators/assignment-operator.md +++ b/docs/csharp/language-reference/operators/assignment-operator.md @@ -1,12 +1,11 @@ --- title: "Assignment operators - assign an expression to a variable" description: "C# Assignment sets the value of the expression. Alternatively, `ref` assignment sets the reference of a reference variable." -ms.date: 11/21/2024 +ms.date: 04/04/2025 f1_keywords: - "=_CSharpKeyword" helpviewer_keywords: - "= operator [C#]" -ms.assetid: d802a6d5-32f0-42b8-b180-12f5a081bfc1 --- # Assignment operators (C# reference) @@ -32,6 +31,8 @@ The left-hand operand of an assignment receives the *value* of the right-hand op This operation is called *value assignment*: the value is assigned. +Beginning with C# 14, the left hand side of a value assignment can include a [null conditional member expression](./member-access-operators.md#null-conditional-operators--and-), such as `?.` or `?[]`. If the left hand side is null, the right hand side expression isn't evaluated. + ## ref assignment *Ref assignment* `= ref` makes its left-hand operand an alias to the right-hand operand, as the following example demonstrates: @@ -66,11 +67,11 @@ x = x op y Except that `x` is only evaluated once. -The [arithmetic](arithmetic-operators.md#compound-assignment), [Boolean logical](boolean-logical-operators.md#compound-assignment), and [bitwise logical and shift](bitwise-and-shift-operators.md#compound-assignment) operators all support compount assignment. +The [arithmetic](arithmetic-operators.md#compound-assignment), [Boolean logical](boolean-logical-operators.md#compound-assignment), and [bitwise logical and shift](bitwise-and-shift-operators.md#compound-assignment) operators all support compound assignment. ## Null-coalescing assignment -You can use the null-coalescing assignment operator `??=` to assign the value of its right-hand operand to its left-hand operand only if the left-hand operand evaluates to `null`. For more information, see the [?? and ??= operators](null-coalescing-operator.md) article. +You can use the null-coalescing assignment operator `??=` to assign the value of its right-hand operand to its left-hand operand only if the left-hand operand evaluates to `null`. For more information, see the [`??` and `??=` operators](null-coalescing-operator.md) article. ## Operator overloadability diff --git a/docs/csharp/language-reference/operators/member-access-operators.md b/docs/csharp/language-reference/operators/member-access-operators.md index 93f2983fc6da5..566e7349802aa 100644 --- a/docs/csharp/language-reference/operators/member-access-operators.md +++ b/docs/csharp/language-reference/operators/member-access-operators.md @@ -1,7 +1,7 @@ --- title: "Member access and null-conditional operators and expressions:" description: "C# operators that you use to access type members or null-conditionally access type members. These operators include the dot operator - `.`, indexers - `[`, `]`, `^` and `..`, and invocation - `(`, `)`." -ms.date: 07/31/2024 +ms.date: 04/04/2025 author: pkulikov f1_keywords: - "._CSharpKeyword" @@ -35,7 +35,7 @@ helpviewer_keywords: --- # Member access operators and expressions - the dot, indexer, and invocation operators. -You use several operators and expressions to access a type member. These operators include member access (`.`), array element or indexer access (`[]`), index-from-end (`^`), range (`..`), null-conditional operators (`?.` and `?[]`), and method invocation (`()`). These include the *null-conditional* member access (`?.`), and indexer access (`?[]`) operators. +You use several operators and expressions to access a type member. Member access operators include member access (`.`), array element, or indexer access (`[]`), index-from-end (`^`), range (`..`), null-conditional operators (`?.` and `?[]`), and method invocation (`()`). These include the *null-conditional* member access (`?.`), and indexer access (`?[]`) operators. - [`.` (member access)](#member-access-expression-): to access a member of a namespace or a type - [`[]` (array element or indexer access)](#indexer-operator-): to access an array element or a type indexer @@ -138,7 +138,7 @@ The following examples demonstrate the usage of the `?.` and `?[]` operators: :::code language="csharp" source="snippets/shared/MemberAccessOperators.cs" id="SnippetNullConditional" interactive="try-dotnet-method"::: :::code language="csharp" source="snippets/shared/MemberAccessOperators2.cs" interactive="try-dotnet"::: -The first of the preceding two examples also uses the [null-coalescing operator `??`](null-coalescing-operator.md) to specify an alternative expression to evaluate in case the result of a null-conditional operation is `null`. +The first preceding example also uses the [null-coalescing operator `??`](null-coalescing-operator.md) to specify an alternative expression to evaluate in case the result of a null-conditional operation is `null`. If `a.x` or `a[x]` is of a non-nullable value type `T`, `a?.x` or `a?[x]` is of the corresponding [nullable value type](../builtin-types/nullable-value-types.md) `T?`. If you need an expression of type `T`, apply the null-coalescing operator `??` to a null-conditional expression, as the following example shows: @@ -147,9 +147,23 @@ If `a.x` or `a[x]` is of a non-nullable value type `T`, `a?.x` or `a?[x]` is of In the preceding example, if you don't use the `??` operator, `numbers?.Length < 2` evaluates to `false` when `numbers` is `null`. > [!NOTE] -> The `?.` operator evaluates its left-hand operand no more than once, guaranteeing that it cannot be changed to `null` after being verified as non-null. +> The `?.` operator evaluates its left-hand operand no more than once, guaranteeing that it can't be changed to `null` after being verified as non-null. -The null-conditional member access operator `?.` is also known as the Elvis operator. +Beginning in C# 14, assignment is permissible with a null conditional access expression (`?.` and `?[]`) on reference types. For example, see the following method: + +:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="NullForgivingAssignment"::: + +The preceding example shows assignment to a property and an indexed element on a reference type that might be null. An important behavior for this assignment is that the expression on the right-hand side of the `=` is evaluated only when the left-hand side is known to be non-null. For example, in the following code, the function `GenerateNextIndex` is called only when the `values` array isn't null. If the `values` array is null, `GenerateNextIndex` isn't called: + +:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="NullForgivingAssignment"::: + +In other words, the preceding code is equivalent to the following code using an `if` statement for the null check: + +:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="EquivalentIfStatement"::: + +In addition to assignment, any form of [compound assignment](./assignment-operator.md#compound-assignment), such as `+=` or `-=`, are allowed. However, increment (`++`) and decrement (`--`) aren't allowed. + +This enhancement doesn't classify a null conditional expression as a variable. It can't be `ref` assigned, nor can it be assigned to a `ref` variable or passed to a method as a `ref` or `out` argument. ### Thread-safe delegate invocation @@ -175,7 +189,7 @@ The preceding example is a thread-safe way to ensure that only a non-null `handl Use parentheses, `()`, to call a [method](../../programming-guide/classes-and-structs/methods.md) or invoke a [delegate](../../programming-guide/delegates/index.md). -The following example demonstrates how to call a method, with or without arguments, and invoke a delegate: +The following code demonstrates how to call a method, with or without arguments, and invoke a delegate: :::code language="csharp" source="snippets/shared/MemberAccessOperators.cs" id="Invocation" interactive="try-dotnet-method"::: diff --git a/docs/csharp/language-reference/operators/null-coalescing-operator.md b/docs/csharp/language-reference/operators/null-coalescing-operator.md index bb2fdf70db930..fdf464e33c070 100644 --- a/docs/csharp/language-reference/operators/null-coalescing-operator.md +++ b/docs/csharp/language-reference/operators/null-coalescing-operator.md @@ -1,7 +1,7 @@ --- title: "?? and ??= operators - null-coalescing operators" description: "The `??` and `??=` operators are the C# null-coalescing operators. They return the value of the left-hand operand if it isn't null. Otherwise, they return the value of the right-hand operand" -ms.date: 11/28/2022 +ms.date: 04/04/2025 f1_keywords: - "??_CSharpKeyword" - "??=_CSharpKeyword" @@ -10,7 +10,6 @@ helpviewer_keywords: - "?? operator [C#]" - "null-coalescing assignment [C#]" - "??= operator [C#]" -ms.assetid: 088b1f0d-c1af-4fe1-b4b8-196fd5ea9132 --- # ?? and ??= operators - the null-coalescing operators @@ -20,13 +19,13 @@ ms.assetid: 088b1f0d-c1af-4fe1-b4b8-196fd5ea9132 The null-coalescing operator `??` returns the value of its left-hand operand if it isn't `null`; otherwise, it evaluates the right-hand operand and returns its result. The `??` operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null. The null-coalescing assignment operator `??=` assigns the value of its right-hand operand to its left-hand operand only if the left-hand operand evaluates to `null`. The `??=` operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null. -[!code-csharp[null-coalescing assignment](snippets/shared/NullCoalescingOperator.cs#Assignment)] +:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="Assignment"::: The left-hand operand of the `??=` operator must be a variable, a [property](../../programming-guide/classes-and-structs/properties.md), or an [indexer](../../programming-guide/indexers/index.md) element. The type of the left-hand operand of the `??` and `??=` operators can't be a non-nullable value type. In particular, you can use the null-coalescing operators with unconstrained type parameters: -[!code-csharp[unconstrained type parameter](snippets/shared/NullCoalescingOperator.cs#UnconstrainedType)] +:::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="UnconstrainedType"::: The null-coalescing operators are right-associative. That is, expressions of the form @@ -48,17 +47,17 @@ The `??` and `??=` operators can be useful in the following scenarios: - In expressions with the [null-conditional operators `?.` and `?[]`](member-access-operators.md#null-conditional-operators--and-), you can use the `??` operator to provide an alternative expression to evaluate in case the result of the expression with null-conditional operations is `null`: - [!code-csharp-interactive[with null-conditional](snippets/shared/NullCoalescingOperator.cs#WithNullConditional)] + :::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="WithNullConditional" interactive="try-dotnet-method"::: - When you work with [nullable value types](../builtin-types/nullable-value-types.md) and need to provide a value of an underlying value type, use the `??` operator to specify the value to provide in case a nullable type value is `null`: - [!code-csharp-interactive[with nullable types](snippets/shared/NullCoalescingOperator.cs#WithNullableTypes)] + :::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="WithNullableTypes" interactive="try-dotnet-method"::: Use the method if the value to be used when a nullable type value is `null` should be the default value of the underlying value type. - You can use a [`throw` expression](../statements/exception-handling-statements.md#the-throw-expression) as the right-hand operand of the `??` operator to make the argument-checking code more concise: - [!code-csharp[with throw expression](snippets/shared/NullCoalescingOperator.cs#WithThrowExpression)] + :::code language="csharp" source="snippets/shared/NullCoalescingOperator.cs" id="WithThrowExpression" interactive="try-dotnet-method"::: The preceding example also demonstrates how to use [expression-bodied members](../../programming-guide/statements-expressions-operators/expression-bodied-members.md) to define a property. diff --git a/docs/csharp/language-reference/operators/snippets/shared/NullCoalescingOperator.cs b/docs/csharp/language-reference/operators/snippets/shared/NullCoalescingOperator.cs index 6c67c49fbcb1c..387f8b518325f 100644 --- a/docs/csharp/language-reference/operators/snippets/shared/NullCoalescingOperator.cs +++ b/docs/csharp/language-reference/operators/snippets/shared/NullCoalescingOperator.cs @@ -1,4 +1,6 @@ -namespace operators; +using System.Diagnostics.CodeAnalysis; + +namespace operators; public static class NullCoalescingOperator { @@ -9,6 +11,35 @@ public static void Examples() NullCoalescingAssignment(); } + public record class Human(string FirstName, string LastName) + { + public string FirstName { get; set; } = FirstName; + } + public static void AddMessageAtIndex() + { + List messages = new List(10); + Human person = new Human("First", "Last"); + // + person?.FirstName = "Scott"; + messages?[5] = "five"; + // + + int index = 0; + int[] values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + // + values?[2] = GenerateNextIndex(); + int GenerateNextIndex() => index++; + // + + // + if (values is not null) + { + values[2] = GenerateNextIndex(); + } + // + } + private static void WithNullConditional() { // diff --git a/docs/csharp/language-reference/operators/snippets/shared/operators.csproj b/docs/csharp/language-reference/operators/snippets/shared/operators.csproj index 281a65c5676c9..d3f3c672e90e0 100644 --- a/docs/csharp/language-reference/operators/snippets/shared/operators.csproj +++ b/docs/csharp/language-reference/operators/snippets/shared/operators.csproj @@ -6,7 +6,6 @@ enable true true - 7022 preview diff --git a/docs/csharp/specification/toc.yml b/docs/csharp/specification/toc.yml index bcc71fe59011e..ef2b617f584c5 100644 --- a/docs/csharp/specification/toc.yml +++ b/docs/csharp/specification/toc.yml @@ -175,6 +175,8 @@ items: href: ../../../_csharplang/proposals/unbound-generic-types-in-nameof.md - name: Overload resolution priority href: ../../../_csharplang/proposals/csharp-13.0/overload-resolution-priority.md + - name: Null conditional assignment + href: ../../../_csharplang/proposals/null-conditional-assignment.md - name: Statements items: - name: Global using directive diff --git a/docs/csharp/whats-new/csharp-14.md b/docs/csharp/whats-new/csharp-14.md index a6cf98faab19d..4b2509bf9e5f2 100644 --- a/docs/csharp/whats-new/csharp-14.md +++ b/docs/csharp/whats-new/csharp-14.md @@ -1,13 +1,14 @@ --- title: What's new in C# 14 description: Get an overview of the new features in C# 14. C# 14 ships with .NET 10. -ms.date: 02/19/2025 +ms.date: 04/04/2025 ms.topic: whats-new --- # What's new in C# 14 C# 14 includes the following new features. You can try these features using the latest [Visual Studio 2022](https://visualstudio.microsoft.com/vs/preview/) version or the [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet): +- [Null-conditional assignment](#null-conditional-assignment) - [`nameof` supports unbound generic types](#unbound-generic-types-and-nameof) - [More implicit conversions for `Span` and `ReadOnlySpan`](#implicit-span-conversions) - [Modifiers on simple lambda parameters](#simple-lambda-parameters-with-modifiers) @@ -99,6 +100,31 @@ Only the implementing declaration of a partial constructor can include a constru The implementing declaration of a partial event must include `add` and `remove` accessors. The defining declaration declares a field-like event. +## Null conditional assignment + +The null conditional member access operators, `?.` and ``?[]`, can now be used on the left hand side of an assignment or compound assignment. + +Before C# 14, you needed to null-check a variable before assigning to a property: + +```csharp +if (customer is not null) +{ + customer.Order = GetCurrentOrder(); +} +``` + +You can simplify the preceding code using the `?.` operator: + +```csharp +customer?.Order = GetCurrentOrder(); +``` + +The right side of the `=` operator is evaluated only when the left side is not null. If `customer` is null, the code won't call `GetCurrentOrder`. + +In addition to assignment, you can use null conditional member access operators with compound assignment operators (`+=`, `-=`, and others). However, increment and decrement, `++` and `--`, aren't allowed. + +You can learn more in the language reference article on the [conditional member access](../language-reference/operators/member-access-operators.md#null-conditional-operators--and-) and the feature specification for [null conditional assignment](~/_csharplang/proposals/null-conditional-assignment.md) + ## See also - [What's new in .NET 10](../../core/whats-new/dotnet-10/overview.md) diff --git a/docs/fundamentals/runtime-libraries/system-globalization-persiancalendar.md b/docs/fundamentals/runtime-libraries/system-globalization-persiancalendar.md index 54e7e94c6eb35..9fc0b310e8b13 100644 --- a/docs/fundamentals/runtime-libraries/system-globalization-persiancalendar.md +++ b/docs/fundamentals/runtime-libraries/system-globalization-persiancalendar.md @@ -1,7 +1,7 @@ --- title: System.Globalization.PersianCalendar class description: Learn more about the System.Globalization.PersianCalendar class. -ms.date: 12/28/2023 +ms.date: 04/09/2025 ms.topic: conceptual --- # class @@ -19,24 +19,18 @@ The Persian calendar is based on a solar year and is approximately 365 days long Each of the first six months in the Persian calendar has 31 days, each of the next five months has 30 days, and the last month has 29 days in a common year and 30 days in a leap year. A leap year is a year that, when divided by 33, has a remainder of 1, 5, 9, 13, 17, 22, 26, or 30. For example, the year 1370 is a leap year because dividing it by 33 yields a remainder of 17. There are approximately eight leap years in every 33-year cycle. -## The PersianCalendar class and .NET Framework versions +## The PersianCalendar class and .NET versions Starting with .NET Framework 4.6, the class uses the Hijri solar astronomical algorithm rather than an observational algorithm to calculate dates. This makes the implementation consistent with the Persian calendar in use in Iran and Afghanistan, the two countries in which the Persian calendar is in most widespread use. The change affects all apps running on .NET Framework 4 or later if .NET Framework 4.6 is installed. As a result of the changed algorithm: - The two algorithms should return identical results when converting dates between 1800 and 2123 in the Gregorian calendar. - -- The two algorithms might return differentresults when converting dates before 1800 and after 2123 in the Gregorian calendar. - -- The property value has changed from March 21, 0622 in the Gregorian calendar to March 22, 0622 in the Gregorian calendar. - -- The property value has changed from the 10th day of the 10th month of the year 9378 in the Persian calendar to the 13th day of the 10th month of the year 9378 in the Persian calendar. - -- The method may return a different result than it did previously. +- The two algorithms might return different results when converting dates before 1800 and after 2123 in the Gregorian calendar. +- The property value has changed from March 21, 0622 in the Gregorian calendar to March 22, 0622 in the Gregorian calendar. +- The property value has changed from the 10th day of the 10th month of the year 9378 in the Persian calendar to the 13th day of the 10th month of the year 9378 in the Persian calendar. +- The method might return a different result than it did previously. ## Use the PersianCalendar class -Applications use a object to calculate dates in the Persian calendar or convert Persian dates to and from Gregorian dates. - -You cannot use a object as the default calendar for a culture. The default calendar is specified by the property and must be one of the calendars returned by the property. Currently, the class is not an optional calendar for any culture supported by the class and consequently cannot be a default calendar. +You can use a object to calculate dates in the Persian calendar or convert Persian dates to and from Gregorian dates. The Persian calendar is the [default calendar](xref:System.Globalization.CultureInfo.Calendar) for cultures such as Persian (Afghanistan) and Central Kurdish (Iran). diff --git a/docs/fundamentals/runtime-libraries/system-uri.md b/docs/fundamentals/runtime-libraries/system-uri.md index 389d014f142a2..fa7e940774292 100644 --- a/docs/fundamentals/runtime-libraries/system-uri.md +++ b/docs/fundamentals/runtime-libraries/system-uri.md @@ -7,7 +7,7 @@ ms.date: 12/31/2023 [!INCLUDE [context](includes/context.md)] -A URI is a compact representation of a resource available to your application on the intranet or internet. The class defines the properties and methods for handling URIs, including parsing, comparing, and combining. The class properties are read-only; to create a modifiable object, use the class. +A uniform resource identifier (URI) is a compact representation of a resource available to your application on the intranet or internet. The class defines the properties and methods for handling URIs, including parsing, comparing, and combining. The class properties are read-only; to create a modifiable object, use the class. Relative URIs (for example, "/new/index.htm") must be expanded with respect to a base URI so that they are absolute. The method is provided to convert absolute URIs to relative URIs when necessary. @@ -16,24 +16,16 @@ The constructors do not escape URI strings if the string is a The properties return a canonical data representation in escaped encoding, with all characters with Unicode values greater than 127 replaced with their hexadecimal equivalents. To put the URI in canonical form, the constructor performs the following steps: - Converts the URI scheme to lowercase. - - Converts the host name to lowercase. - - If the host name is an IPv6 address, the canonical IPv6 address is used. ScopeId and other optional IPv6 data are removed. - - Removes default and empty port numbers. - - Converts implicit file paths without the file:// scheme (for example, "C:\my\file") to explicit file paths with the file:// scheme. - - Escaped characters (also known as percent-encoded octets) that don't have a reserved purpose are decoded (also known as being unescaped). These unreserved characters include uppercase and lowercase letters (%41-%5A and %61-%7A), decimal digits (%30-%39), hyphen (%2D), period (%2E), underscore (%5F), and tilde (%7E). - -- Canonicalizes the path for hierarchical URIs by compacting sequences such as /./, /../, and // (whether or not the sequence is escaped). Note that there are some schemes for which these sequences are not compacted. - +- Canonicalizes the path for hierarchical URIs by compacting sequences such as `/./` and `/../` (whether or not the sequence is escaped). Note that there are some schemes for which these sequences are not compacted. - For hierarchical URIs, if the host is not terminated with a forward slash (/), one is added. - - By default, any reserved characters in the URI are escaped in accordance with RFC 2396. This behavior changes if International Resource Identifiers or International Domain Name parsing is enabled in which case reserved characters in the URI are escaped in accordance with RFC 3986 and RFC 3987. -As part of canonicalization in the constructor for some schemes, dot-segments and empty segments (`/./`, `/../`, and `//`) are compacted (in other words, they are removed). The schemes for which compacts segments include http, https, tcp, net.pipe, and net.tcp. For some other schemes, these sequences are not compacted. The following code snippet shows how compacting looks in practice. The escaped sequences are unescaped, if necessary, and then compacted. +As part of canonicalization in the constructor for some schemes, dot-segments (`/./` and `/../`) are compacted (in other words, they're removed). The schemes for which compacts segments include http, https, tcp, net.pipe, and net.tcp. For some other schemes, these sequences are not compacted. The following code snippet shows how compacting looks in practice. The escaped sequences are unescaped, if necessary, and then compacted. ```csharp var uri = new Uri("http://myUrl/../.."); // http scheme, unescaped @@ -64,7 +56,7 @@ Some URIs include a fragment identifier or a query or both. A fragment identifie ## International resource identifier support -Web addresses are typically expressed using uniform resource identifiers that consist of a very restricted set of characters: +Web addresses are typically expressed using URIs that consist of a very restricted set of characters: - Upper and lower case ASCII letters from the English alphabet. - Digits from 0 to 9. @@ -92,15 +84,15 @@ There are three possible values for IDN depending on the DNS servers that are us - idn enabled = All - This value will convert any Unicode domain names to their Punycode equivalents (IDN names). + Converts any Unicode domain names to their Punycode equivalents (IDN names). - idn enabled = AllExceptIntranet - This value will convert all Unicode domain names not on the local Intranet to use the Punycode equivalents (IDN names). In this case to handle international names on the local Intranet, the DNS servers that are used for the Intranet should support Unicode name resolution. + Converts all Unicode domain names not on the local Intranet to use the Punycode equivalents (IDN names). In this case, to handle international names on the local Intranet, the DNS servers that are used for the Intranet should support Unicode name resolution. - idn enabled = None - This value will not convert any Unicode domain names to use Punycode. This is the default value. + No Unicode domain names are converted to use Punycode. This is the default value. Normalization and character checking are done according to the latest IRI rules in RFC 3986 and RFC 3987. @@ -121,7 +113,7 @@ Uri uri1 = new Uri("C:/test/path/file.txt") // Implicit file path. Uri uri2 = new Uri("file:///C:/test/path/file.txt") // Explicit file path. ``` -These implicit file paths are not compliant with the URI specification and so should be avoided when possible. When using .NET Core on Unix-based systems, implicit file paths can be especially problematic, because an absolute implicit file path is *indistinguishable* from a relative path. When such ambiguity is present, default to interpreting the path as an absolute URI. +These implicit file paths are not compliant with the URI specification and should be avoided when possible. When using .NET Core on Unix-based systems, implicit file paths can be especially problematic, because an absolute implicit file path is *indistinguishable* from a relative path. When such ambiguity is present, default to interpreting the path as an absolute URI. ## Security considerations diff --git a/docs/standard/memory-and-spans/memory-t-usage-guidelines.md b/docs/standard/memory-and-spans/memory-t-usage-guidelines.md index 33ce95cd7ff51..158385eee37e3 100644 --- a/docs/standard/memory-and-spans/memory-t-usage-guidelines.md +++ b/docs/standard/memory-and-spans/memory-t-usage-guidelines.md @@ -1,8 +1,8 @@ --- title: "Memory and Span usage guidelines" description: This article describes Memory and Span, which are buffers of structured data in .NET that can be used in pipelines. -ms.date: 04/19/2023 -helpviewer_keywords: +ms.date: 04/09/2025 +helpviewer_keywords: - "Memory<T> and Span<T> best practices" - "using Memory<T> and Span<T>" --- @@ -19,7 +19,6 @@ Buffers can be passed around between APIs and can sometimes be accessed from mul - **Ownership**. The owner of a buffer instance is responsible for lifetime management, including destroying the buffer when it's no longer in use. All buffers have a single owner. Generally the owner is the component that created the buffer or that received the buffer from a factory. Ownership can also be transferred; **Component-A** can relinquish control of the buffer to **Component-B**, at which point **Component-A** may no longer use the buffer, and **Component-B** becomes responsible for destroying the buffer when it's no longer in use. - **Consumption**. The consumer of a buffer instance is allowed to use the buffer instance by reading from it and possibly writing to it. Buffers can have one consumer at a time unless some external synchronization mechanism is provided. The active consumer of a buffer isn't necessarily the buffer's owner. - - **Lease**. The lease is the length of time that a particular component is allowed to be the consumer of the buffer. The following pseudo-code example illustrates these three concepts. `Buffer` in the pseudo-code represents a or buffer of type . The `Main` method instantiates the buffer, calls the `WriteInt32ToBuffer` method to write the string representation of an integer to the buffer, and then calls the `DisplayBufferToConsole` method to display the value of the buffer. @@ -64,21 +63,19 @@ The `WriteInt32ToBuffer` method has a lease on (can consume) the buffer between As the [Owners, consumers, and lifetime management](#owners-consumers-and-lifetime-management) section notes, a buffer always has an owner. .NET supports two ownership models: - A model that supports single ownership. A buffer has a single owner for its entire lifetime. - - A model that supports ownership transfer. Ownership of a buffer can be transferred from its original owner (its creator) to another component, which then becomes responsible for the buffer's lifetime management. That owner can in turn transfer ownership to another component, and so on. You use the interface to explicitly manage the ownership of a buffer. supports both ownership models. The component that has an reference owns the buffer. The following example uses an instance to reflect the ownership of a buffer. -[!code-csharp[ownership](~/samples/snippets/standard/buffers/memory-t/owner/owner.cs)] +:::code language="csharp" source="snippets/usage-guidelines/owner/owner.cs"::: -We can also write this example with the [`using` statement](../../csharp/language-reference/statements/using.md): +You can also write this example with the [`using` statement](../../csharp/language-reference/statements/using.md): -[!code-csharp[ownership-using](~/samples/snippets/standard/buffers/memory-t/owner-using/owner-using.cs)] +:::code language="csharp" source="snippets/usage-guidelines/owner-using/owner-using.cs"::: In this code: - The `Main` method holds the reference to the instance, so the `Main` method is the owner of the buffer. - - The `WriteInt32ToBuffer` and `DisplayBufferToConsole` methods accept as a public API. Therefore, they are consumers of the buffer. These methods consume the buffer one at a time. Although the `WriteInt32ToBuffer` method is intended to write a value to the buffer, the `DisplayBufferToConsole` method isn't intended to. To reflect this, it could have accepted an argument of type . For more information on , see [Rule #2: Use ReadOnlySpan\ or ReadOnlyMemory\ if the buffer should be read-only](#rule-2). @@ -88,26 +85,35 @@ Although the `WriteInt32ToBuffer` method is intended to write a value to the buf You can create a instance without using . In this case, ownership of the buffer is implicit rather than explicit, and only the single-owner model is supported. You can do this by: - Calling one of the constructors directly, passing in a `T[]`, as the following example does. - - Calling the [String.AsMemory](xref:System.MemoryExtensions.AsMemory(System.String)) extension method to produce a `ReadOnlyMemory` instance. -[!code-csharp[ownerless-memory](~/samples/snippets/standard/buffers/memory-t/ownerless/ownerless.cs)] +:::code language="csharp" source="snippets/usage-guidelines/ownerless/ownerless.cs"::: The method that initially creates the instance is the implicit owner of the buffer. Ownership cannot be transferred to any other component because there is no instance to facilitate the transfer. (As an alternative, you can also imagine that the runtime's garbage collector owns the buffer, and all methods just consume the buffer.) ## Usage guidelines -Because a memory block is owned but is intended to be passed to multiple components, some of which may operate upon a particular memory block simultaneously, it's important to establish guidelines for using both and . Guidelines are necessary because it's possible for a component to: +Because a memory block is owned but is intended to be passed to multiple components, some of which might operate upon a particular memory block simultaneously, it's important to establish guidelines for using both and . Guidelines are necessary because it's possible for a component to: - Retain a reference to a memory block after its owner has released it. - - Operate on a buffer at the same time that another component is operating on it, in the process corrupting the data in the buffer. -- While the stack-allocated nature of optimizes performance and makes the preferred type for operating on a memory block, it also subjects to some major restrictions. It's important to know when to use a and when to use . +While the stack-allocated nature of optimizes performance and makes the preferred type for operating on a memory block, it also subjects to some major restrictions. It's important to know when to use a and when to use . The following are our recommendations for successfully using and its related types. Guidance that applies to and also applies to and unless noted otherwise. -**Rule #1: For a synchronous API, use Span\ instead of Memory\ as a parameter if possible.** +- [Rule #1: For a synchronous API, use `Span` instead of `Memory` as a parameter if possible](#rule-1-for-a-synchronous-api-use-spant-instead-of-memoryt-as-a-parameter-if-possible) +- [Rule #2: Use `ReadOnlySpan` or `ReadOnlyMemory` if the buffer should be read-only](#rule-2-use-readonlyspant-or-readonlymemoryt-if-the-buffer-should-be-read-only) +- [Rule #3: If your method accepts `Memory` and returns `void`, you must not use the `Memory` instance after your method returns](#rule-3-if-your-method-accepts-memoryt-and-returns-void-you-must-not-use-the-memoryt-instance-after-your-method-returns) +- [Rule #4: If your method accepts a `Memory` and returns a Task, you must not use the `Memory` instance after the Task transitions to a terminal state](#rule-4-if-your-method-accepts-a-memoryt-and-returns-a-task-you-must-not-use-the-memoryt-instance-after-the-task-transitions-to-a-terminal-state) +- [Rule #5: If your constructor accepts `Memory` as a parameter, instance methods on the constructed object are assumed to be consumers of the `Memory` instance](#rule-5-if-your-constructor-accepts-memoryt-as-a-parameter-instance-methods-on-the-constructed-object-are-assumed-to-be-consumers-of-the-memoryt-instance) +- [Rule #6: If you have a settable `Memory`-typed property (or an equivalent instance method) on your type, instance methods on that object are assumed to be consumers of the `Memory` instance](#rule-6-if-you-have-a-settable-memoryt-typed-property-or-an-equivalent-instance-method-on-your-type-instance-methods-on-that-object-are-assumed-to-be-consumers-of-the-memoryt-instance) +- [Rule #7: If you have an `IMemoryOwner` reference, you must at some point dispose of it or transfer its ownership (but not both)](#rule-7-if-you-have-an-imemoryownert-reference-you-must-at-some-point-dispose-of-it-or-transfer-its-ownership-but-not-both) +- [Rule #8: If you have an `IMemoryOwner` parameter in your API surface, you are accepting ownership of that instance](#rule-8-if-you-have-an-imemoryownert-parameter-in-your-api-surface-you-are-accepting-ownership-of-that-instance) +- [Rule #9: If you're wrapping a synchronous P/Invoke method, your API should accept `Span` as a parameter](#rule-9-if-youre-wrapping-a-synchronous-pinvoke-method-your-api-should-accept-spant-as-a-parameter) +- [Rule #10: If you're wrapping an asynchronous p/invoke method, your API should accept `Memory` as a parameter](#rule-10-if-youre-wrapping-an-asynchronous-pinvoke-method-your-api-should-accept-memoryt-as-a-parameter) + +### Rule #1: For a synchronous API, use Span\ instead of Memory\ as a parameter if possible is more versatile than and can represent a wider variety of contiguous memory buffers. also offers better performance than . Finally, you can use the property to convert a instance to a , although Span\-to-Memory\ conversion isn't possible. So if your callers happen to have a instance, they'll be able to call your methods with parameters anyway. @@ -117,7 +123,7 @@ Sometimes, you'll have to use a parameter instead of a -**Rule #2: Use ReadOnlySpan\ or ReadOnlyMemory\ if the buffer should be read-only.** +### Rule #2: Use ReadOnlySpan\ or ReadOnlyMemory\ if the buffer should be read-only In the earlier examples, the `DisplayBufferToConsole` method only reads from the buffer; it doesn't modify the contents of the buffer. The method signature should be changed to the following. @@ -125,7 +131,7 @@ In the earlier examples, the `DisplayBufferToConsole` method only reads from the void DisplayBufferToConsole(ReadOnlyMemory buffer); ``` -In fact, if we combine this rule and Rule #1, we can do even better and rewrite the method signature as follows: +In fact, if you combine this rule and Rule #1, we can do even better and rewrite the method signature as follows: ```csharp void DisplayBufferToConsole(ReadOnlySpan buffer); @@ -133,11 +139,11 @@ void DisplayBufferToConsole(ReadOnlySpan buffer); The `DisplayBufferToConsole` method now works with virtually every buffer type imaginable: `T[]`, storage allocated with [stackalloc](../../csharp/language-reference/operators/stackalloc.md), and so on. You can even pass a directly into it! For more information, see GitHub issue [dotnet/docs #25551](https://github.com/dotnet/docs/issues/25551). -**Rule #3: If your method accepts Memory\ and returns `void`, you must not use the Memory\ instance after your method returns.** +### Rule #3: If your method accepts Memory\ and returns `void`, you must not use the Memory\ instance after your method returns This relates to the "lease" concept mentioned earlier. A void-returning method's lease on the instance begins when the method is entered, and it ends when the method exits. Consider the following example, which calls `Log` in a loop based on input from the console. -[!code-csharp[void-returning](~/samples/snippets/standard/buffers/memory-t/void-returning/void-returning.cs#1)] +:::code language="csharp" source="snippets/usage-guidelines/void-returning/void-returning.cs"::: If `Log` is a fully synchronous method, this code will behave as expected because there is only one active consumer of the memory instance at any given time. But imagine instead that `Log` has this implementation. @@ -161,23 +167,23 @@ There are several ways to resolve this: - The `Log` method can return a instead of `void`, as the following implementation of the `Log` method does. - [!code-csharp[task-returning](~/samples/snippets/standard/buffers/memory-t/task-returning2/task-returning2.cs#1)] + :::code language="csharp" source="snippets/usage-guidelines/task-returning-async/task-returning-async.cs" id="Snippet1"::: - `Log` can instead be implemented as follows: - [!code-csharp[defensive-copy](~/samples/snippets/standard/buffers/memory-t/task-returning/task-returning.cs#1)] + :::code language="csharp" source="snippets/usage-guidelines/task-returning/task-returning.cs" id="Snippet1"::: -**Rule #4: If your method accepts a Memory\ and returns a Task, you must not use the Memory\ instance after the Task transitions to a terminal state.** +### Rule #4: If your method accepts a Memory\ and returns a Task, you must not use the Memory\ instance after the Task transitions to a terminal state This is just the async variant of Rule #3. The `Log` method from the earlier example can be written as follows to comply with this rule: -[!code-csharp[task-returning-async](~/samples/snippets/standard/buffers/memory-t/task-returning-async/task-returning-async.cs#1)] +:::code language="csharp" source="snippets/usage-guidelines/task-returning-async/task-returning-async.cs" id="Snippet1"::: Here, "terminal state" means that the task transitions to a completed, faulted, or canceled state. In other words, "terminal state" means "anything that would cause await to throw or to continue execution." This guidance applies to methods that return , , , or any similar type. -**Rule #5: If your constructor accepts Memory\ as a parameter, instance methods on the constructed object are assumed to be consumers of the Memory\ instance.** +### Rule #5: If your constructor accepts Memory\ as a parameter, instance methods on the constructed object are assumed to be consumers of the Memory\ instance Consider the following example: @@ -200,7 +206,7 @@ void PrintAllOddValues(ReadOnlyMemory input) Here, the `OddValueExtractor` constructor accepts a `ReadOnlyMemory` as a constructor parameter, so the constructor itself is a consumer of the `ReadOnlyMemory` instance, and all instance methods on the returned value are also consumers of the original `ReadOnlyMemory` instance. This means that `TryReadNextOddValue` consumes the `ReadOnlyMemory` instance, even though the instance isn't passed directly to the `TryReadNextOddValue` method. -**Rule #6: If you have a settable Memory\-typed property (or an equivalent instance method) on your type, instance methods on that object are assumed to be consumers of the Memory\ instance.** +### Rule #6: If you have a settable Memory\-typed property (or an equivalent instance method) on your type, instance methods on that object are assumed to be consumers of the Memory\ instance This is really just a variant of Rule #5. This rule exists because property setters or equivalent methods are assumed to capture and persist their inputs, so instance methods on the same object may utilize the captured state. @@ -220,7 +226,7 @@ class Person } ``` -**Rule #7: If you have an IMemoryOwner\ reference, you must at some point dispose of it or transfer its ownership (but not both).** +### Rule #7: If you have an IMemoryOwner\ reference, you must at some point dispose of it or transfer its ownership (but not both) Since a instance may be backed by either managed or unmanaged memory, the owner must call `Dispose` on when work performed on the instance is complete. Alternatively, the owner may transfer ownership of the instance to a different component, at which point the acquiring component becomes responsible for calling `Dispose` at the appropriate time (more on this later). @@ -228,7 +234,7 @@ Failure to call the `Dispose` method on an . The caller becomes the owner of the returned and is responsible for disposing of the instance when finished. -**Rule #8: If you have an IMemoryOwner\ parameter in your API surface, you are accepting ownership of that instance.** +### Rule #8: If you have an IMemoryOwner\ parameter in your API surface, you are accepting ownership of that instance Accepting an instance of this type signals that your component intends to take ownership of this instance. Your component becomes responsible for proper disposal according to Rule #7. @@ -237,7 +243,7 @@ Any component that transfers ownership of the [!IMPORTANT] > If your constructor accepts as a parameter, its type should implement , and your method should call `Dispose` on the object. -**Rule #9: If you're wrapping a synchronous p/invoke method, your API should accept Span\ as a parameter.** +### Rule #9: If you're wrapping a synchronous p/invoke method, your API should accept Span\ as a parameter According to Rule #1, is generally the correct type to use for synchronous APIs. You can pin instances via the [`fixed`](../../csharp/language-reference/statements/fixed.md) keyword, as in the following example. @@ -277,7 +283,7 @@ public unsafe int ManagedWrapper(Span data) } ``` -**Rule #10: If you're wrapping an asynchronous p/invoke method, your API should accept Memory\ as a parameter.** +### Rule #10: If you're wrapping an asynchronous p/invoke method, your API should accept Memory\ as a parameter Since you cannot use the [`fixed`](../../csharp/language-reference/statements/fixed.md) keyword across asynchronous operations, you use the method to pin instances, regardless of the kind of contiguous memory the instance represents. The following example shows how to use this API to perform an asynchronous p/invoke call. diff --git a/samples/snippets/standard/buffers/memory-t/owner-using/owner-using.cs b/docs/standard/memory-and-spans/snippets/usage-guidelines/owner-using/owner-using.cs similarity index 100% rename from samples/snippets/standard/buffers/memory-t/owner-using/owner-using.cs rename to docs/standard/memory-and-spans/snippets/usage-guidelines/owner-using/owner-using.cs diff --git a/samples/snippets/standard/buffers/memory-t/owner-using/owner-using.csproj b/docs/standard/memory-and-spans/snippets/usage-guidelines/owner-using/owner-using.csproj similarity index 100% rename from samples/snippets/standard/buffers/memory-t/owner-using/owner-using.csproj rename to docs/standard/memory-and-spans/snippets/usage-guidelines/owner-using/owner-using.csproj diff --git a/samples/snippets/standard/buffers/memory-t/owner/owner.cs b/docs/standard/memory-and-spans/snippets/usage-guidelines/owner/owner.cs similarity index 100% rename from samples/snippets/standard/buffers/memory-t/owner/owner.cs rename to docs/standard/memory-and-spans/snippets/usage-guidelines/owner/owner.cs diff --git a/samples/snippets/standard/buffers/memory-t/owner/owner.csproj b/docs/standard/memory-and-spans/snippets/usage-guidelines/owner/owner.csproj similarity index 100% rename from samples/snippets/standard/buffers/memory-t/owner/owner.csproj rename to docs/standard/memory-and-spans/snippets/usage-guidelines/owner/owner.csproj diff --git a/samples/snippets/standard/buffers/memory-t/ownerless/ownerless.cs b/docs/standard/memory-and-spans/snippets/usage-guidelines/ownerless/ownerless.cs similarity index 100% rename from samples/snippets/standard/buffers/memory-t/ownerless/ownerless.cs rename to docs/standard/memory-and-spans/snippets/usage-guidelines/ownerless/ownerless.cs diff --git a/samples/snippets/standard/buffers/memory-t/ownerless/ownerless.csproj b/docs/standard/memory-and-spans/snippets/usage-guidelines/ownerless/ownerless.csproj similarity index 100% rename from samples/snippets/standard/buffers/memory-t/ownerless/ownerless.csproj rename to docs/standard/memory-and-spans/snippets/usage-guidelines/ownerless/ownerless.csproj diff --git a/samples/snippets/standard/buffers/memory-t/task-returning-async/project.csproj b/docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning-async/project.csproj similarity index 100% rename from samples/snippets/standard/buffers/memory-t/task-returning-async/project.csproj rename to docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning-async/project.csproj diff --git a/samples/snippets/standard/buffers/memory-t/task-returning2/task-returning2.cs b/docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning-async/task-returning-async.cs similarity index 100% rename from samples/snippets/standard/buffers/memory-t/task-returning2/task-returning2.cs rename to docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning-async/task-returning-async.cs diff --git a/samples/snippets/standard/buffers/memory-t/task-returning/task-returning.cs b/docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning/task-returning.cs similarity index 100% rename from samples/snippets/standard/buffers/memory-t/task-returning/task-returning.cs rename to docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning/task-returning.cs diff --git a/samples/snippets/standard/buffers/memory-t/task-returning/task-returning.csproj b/docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning/task-returning.csproj similarity index 100% rename from samples/snippets/standard/buffers/memory-t/task-returning/task-returning.csproj rename to docs/standard/memory-and-spans/snippets/usage-guidelines/task-returning/task-returning.csproj diff --git a/samples/snippets/standard/buffers/memory-t/void-returning/void-returning.cs b/docs/standard/memory-and-spans/snippets/usage-guidelines/void-returning/void-returning.cs similarity index 100% rename from samples/snippets/standard/buffers/memory-t/void-returning/void-returning.cs rename to docs/standard/memory-and-spans/snippets/usage-guidelines/void-returning/void-returning.cs diff --git a/samples/snippets/standard/buffers/memory-t/void-returning/void-returning.csproj b/docs/standard/memory-and-spans/snippets/usage-guidelines/void-returning/void-returning.csproj similarity index 100% rename from samples/snippets/standard/buffers/memory-t/void-returning/void-returning.csproj rename to docs/standard/memory-and-spans/snippets/usage-guidelines/void-returning/void-returning.csproj diff --git a/docs/standard/serialization/system-text-json/supported-types.md b/docs/standard/serialization/system-text-json/supported-types.md index ee11a96659ad8..70f6777bad436 100644 --- a/docs/standard/serialization/system-text-json/supported-types.md +++ b/docs/standard/serialization/system-text-json/supported-types.md @@ -51,9 +51,11 @@ The following sections are organized by namespace and show which types are suppo | Type | Serialization | Deserialization | |-------------------------------------------------------------------------------------------------|---------------|-----------------| -| [Single-dimensional arrays](../../../csharp/language-reference/builtin-types/arrays.md#single-dimensional-arrays) | ✔️ | ✔️ | -| [Multi-dimensional arrays](../../../csharp/language-reference/builtin-types/arrays.md#multidimensional-arrays) | ❌ | ❌ | -| [Jagged arrays](../../../csharp/language-reference/builtin-types/arrays.md#jagged-arrays) | ✔️ | ✔️ | +| [Single-dimensional arrays](../../../csharp/language-reference/builtin-types/arrays.md#single-dimensional-arrays)* | ✔️ | ✔️ | +| [Multi-dimensional arrays](../../../csharp/language-reference/builtin-types/arrays.md#multidimensional-arrays) | ❌ | ❌ | +| [Jagged arrays](../../../csharp/language-reference/builtin-types/arrays.md#jagged-arrays) | ✔️ | ✔️ | + +\* `byte[]` is handled specially and serializes as a base64 string, not a JSON array. ### System.Collections namespace diff --git a/samples/snippets/standard/buffers/memory-t/task-returning-async/task-returning-async.cs b/samples/snippets/standard/buffers/memory-t/task-returning-async/task-returning-async.cs deleted file mode 100644 index 83fbc721a700f..0000000000000 --- a/samples/snippets/standard/buffers/memory-t/task-returning-async/task-returning-async.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Buffers; -using System.IO; -using System.Threading.Tasks; - -public class Example -{ - // - // An acceptable implementation. - static Task Log(ReadOnlyMemory message) - { - // Run in the background so that we don't block the main thread while performing IO. - return Task.Run(() => - { - StreamWriter sw = File.AppendText(@".\input-numbers.dat"); - sw.WriteLine(message); - sw.Flush(); - }); - } - // - - // user code - public static void Main() - { - using (var owner = MemoryPool.Shared.Rent()) - { - var memory = owner.Memory; - var span = memory.Span; - while (true) - { - string? s = Console.ReadLine(); - - if (s is null) - return; - - int value = Int32.Parse(s); - if (value < 0) - return; - - int numCharsWritten = ToBuffer(value, span); - Log(memory.Slice(0, numCharsWritten)); - } - } - } - - private static int ToBuffer(int value, Span span) - { - string strValue = value.ToString(); - int length = strValue.Length; - strValue.AsSpan().CopyTo(span.Slice(0, length)); - return length; - } -} diff --git a/samples/snippets/standard/buffers/memory-t/task-returning2/task-returning2.csproj b/samples/snippets/standard/buffers/memory-t/task-returning2/task-returning2.csproj deleted file mode 100644 index 3675843c7dfb1..0000000000000 --- a/samples/snippets/standard/buffers/memory-t/task-returning2/task-returning2.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net8.0 - enable - void_returning - - -