diff --git a/.openpublishing.redirection.aspire.json b/.openpublishing.redirection.aspire.json new file mode 100644 index 0000000000000..d6c5240d56fcc --- /dev/null +++ b/.openpublishing.redirection.aspire.json @@ -0,0 +1,9 @@ +{ + "redirections": [ + { + "source_path_from_root": "/docs/aspire/get-started/upgrade-to-aspire-13.md", + "redirect_url": "https://aspire.dev/whats-new/upgrade-aspire/", + "redirect_document_id": false + } + ] +} diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md index 73c22c783541f..245446159c8dd 100644 --- a/docs/azure/includes/dotnet-all.md +++ b/docs/azure/includes/dotnet-all.md @@ -28,7 +28,7 @@ | Conversational Language Understanding | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Language.Conversations/1.1.0)
NuGet [2.0.0-beta.5](https://www.nuget.org/packages/Azure.AI.Language.Conversations/2.0.0-beta.5) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_1.1.0/sdk/cognitivelanguage/Azure.AI.Language.Conversations/)
GitHub [2.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_2.0.0-beta.5/sdk/cognitivelanguage/Azure.AI.Language.Conversations/) | | Conversations Authoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.AI.Language.Conversations.Authoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations.Authoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations.Authoring_1.0.0-beta.3/sdk/cognitivelanguage/Azure.AI.Language.Conversations.Authoring/) | | Core - Client - AMQP | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Core.Amqp/1.3.1) | [docs](/dotnet/api/overview/azure/Core.Amqp-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Amqp_1.3.1/sdk/core/Azure.Core.Amqp/) | -| Core - Client - Core | NuGet [1.51.0](https://www.nuget.org/packages/Azure.Core/1.51.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.51.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.51.0/sdk/core/Azure.Core/) | +| Core - Client - Core | NuGet [1.51.1](https://www.nuget.org/packages/Azure.Core/1.51.1) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.51.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.51.1/sdk/core/Azure.Core/) | | Core - Client - Core | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Core.Expressions.DataFactory/1.0.0) | [docs](/dotnet/api/overview/azure/Core.Expressions.DataFactory-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Expressions.DataFactory_1.0.0/sdk/core/Azure.Core.Expressions.DataFactory/) | | Core Newtonsoft Json | NuGet [2.0.0](https://www.nuget.org/packages/Microsoft.Azure.Core.NewtonsoftJson/2.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.NewtonsoftJson-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.NewtonsoftJson_2.0.0/sdk/core/Microsoft.Azure.Core.NewtonsoftJson/) | | Core WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.CoreWCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.CoreWCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.CoreWCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.CoreWCF.Azure.StorageQueues/) | @@ -148,7 +148,7 @@ | Functions extension for Storage Queues | NuGet [5.3.7](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/5.3.7) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.Storage.Queues-readme) | GitHub [5.3.7](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.Storage.Queues_5.3.7/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/) | | Functions extension for WebPubSub for SocketIO | NuGet [1.0.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO/1.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO_1.0.0/sdk/webpubsub/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO/) | | Provisioning - App Configuration | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.AppConfiguration/1.1.0) | [docs](/dotnet/api/overview/azure/Provisioning.AppConfiguration-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppConfiguration_1.1.0/sdk/provisioning/Azure.Provisioning.AppConfiguration/) | -| Provisioning - App Containers | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.AppContainers/1.1.0) | [docs](/dotnet/api/overview/azure/Provisioning.AppContainers-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppContainers_1.1.0/sdk/provisioning/Azure.Provisioning.AppContainers/) | +| Provisioning - App Containers | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.AppContainers/1.1.0)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.Provisioning.AppContainers/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/Provisioning.AppContainers-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppContainers_1.1.0/sdk/provisioning/Azure.Provisioning.AppContainers/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppContainers_1.2.0-beta.1/sdk/provisioning/Azure.Provisioning.AppContainers/) | | Provisioning - App Service | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Provisioning.AppService/1.3.1) | [docs](/dotnet/api/overview/azure/Provisioning.AppService-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppService_1.3.1/sdk/provisioning/Azure.Provisioning.AppService/) | | Provisioning - Application Insights | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.ApplicationInsights/1.1.0) | [docs](/dotnet/api/overview/azure/Provisioning.ApplicationInsights-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.ApplicationInsights_1.1.0/sdk/provisioning/Azure.Provisioning.ApplicationInsights/) | | Provisioning - Cognitive Services | NuGet [1.2.0](https://www.nuget.org/packages/Azure.Provisioning.CognitiveServices/1.2.0) | [docs](/dotnet/api/overview/azure/Provisioning.CognitiveServices-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.CognitiveServices_1.2.0/sdk/provisioning/Azure.Provisioning.CognitiveServices/) | @@ -267,7 +267,7 @@ | Resource Management - Event Hubs | NuGet [1.2.1](https://www.nuget.org/packages/Azure.ResourceManager.EventHubs/1.2.1)
NuGet [1.3.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.EventHubs/1.3.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.EventHubs-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.EventHubs_1.2.1/sdk/eventhub/Azure.ResourceManager.EventHubs/)
GitHub [1.3.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.EventHubs_1.3.0-beta.1/sdk/eventhub/Azure.ResourceManager.EventHubs/) | | Resource Management - Extended Location | NuGet [1.1.1](https://www.nuget.org/packages/Azure.ResourceManager.ExtendedLocations/1.1.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ExtendedLocations-readme) | GitHub [1.1.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ExtendedLocations_1.1.1/sdk/extendedlocation/Azure.ResourceManager.ExtendedLocations/) | | Resource Management - Fabric | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.Fabric/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Fabric-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Fabric_1.0.0/sdk/fabric/Azure.ResourceManager.Fabric/) | -| Resource Management - Fileshares | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.FileShares/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.FileShares-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FileShares_1.0.0-beta.1/sdk/fileshares/Azure.ResourceManager.FileShares/) | +| Resource Management - Fileshares | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.FileShares/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.FileShares-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FileShares_1.0.0-beta.2/sdk/fileshares/Azure.ResourceManager.FileShares/) | | Resource Management - Fluid Relay | NuGet [1.1.1](https://www.nuget.org/packages/Azure.ResourceManager.FluidRelay/1.1.1) | [docs](/dotnet/api/overview/azure/ResourceManager.FluidRelay-readme) | GitHub [1.1.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FluidRelay_1.1.1/sdk/fluidrelay/Azure.ResourceManager.FluidRelay/) | | Resource Management - Front Door | NuGet [1.4.1](https://www.nuget.org/packages/Azure.ResourceManager.FrontDoor/1.4.1) | [docs](/dotnet/api/overview/azure/ResourceManager.FrontDoor-readme) | GitHub [1.4.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FrontDoor_1.4.1/sdk/frontdoor/Azure.ResourceManager.FrontDoor/) | | Resource Management - Graph Services | NuGet [1.1.2](https://www.nuget.org/packages/Azure.ResourceManager.GraphServices/1.1.2) | [docs](/dotnet/api/overview/azure/ResourceManager.GraphServices-readme) | GitHub [1.1.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.GraphServices_1.1.2/sdk/graphservices/Azure.ResourceManager.GraphServices/) | @@ -412,7 +412,7 @@ | 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.4](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers/1.0.4) | | | | IoT Operations MQTT | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Iot.Operations.Mqtt/1.0.0) | | | -| IoT Operations Protocol | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Iot.Operations.Protocol/1.0.0) | | | +| IoT Operations Protocol | NuGet [1.0.1](https://www.nuget.org/packages/Azure.Iot.Operations.Protocol/1.0.1) | | | | IoT Operations Services | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Iot.Operations.Services/1.0.0)
NuGet [1.2.0-rc2](https://www.nuget.org/packages/Azure.Iot.Operations.Services/1.2.0-rc2) | | | | Item Templates NetCore | NuGet [4.0.5337](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.ItemTemplates.NetCore/4.0.5337) | | | | Item Templates NetFx | NuGet [4.0.5337](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.ItemTemplates.NetFx/4.0.5337) | | | diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md index 638b709a211e6..976f44bba218f 100644 --- a/docs/azure/includes/dotnet-new.md +++ b/docs/azure/includes/dotnet-new.md @@ -30,7 +30,7 @@ | Conversational Language Understanding | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Language.Conversations/1.1.0)
NuGet [2.0.0-beta.5](https://www.nuget.org/packages/Azure.AI.Language.Conversations/2.0.0-beta.5) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_1.1.0/sdk/cognitivelanguage/Azure.AI.Language.Conversations/)
GitHub [2.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_2.0.0-beta.5/sdk/cognitivelanguage/Azure.AI.Language.Conversations/) | | Conversations Authoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.AI.Language.Conversations.Authoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations.Authoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations.Authoring_1.0.0-beta.3/sdk/cognitivelanguage/Azure.AI.Language.Conversations.Authoring/) | | Core - Client - AMQP | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Core.Amqp/1.3.1) | [docs](/dotnet/api/overview/azure/Core.Amqp-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Amqp_1.3.1/sdk/core/Azure.Core.Amqp/) | -| Core - Client - Core | NuGet [1.51.0](https://www.nuget.org/packages/Azure.Core/1.51.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.51.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.51.0/sdk/core/Azure.Core/) | +| Core - Client - Core | NuGet [1.51.1](https://www.nuget.org/packages/Azure.Core/1.51.1) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.51.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.51.1/sdk/core/Azure.Core/) | | Core - Client - Core | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Core.Expressions.DataFactory/1.0.0) | [docs](/dotnet/api/overview/azure/Core.Expressions.DataFactory-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Expressions.DataFactory_1.0.0/sdk/core/Azure.Core.Expressions.DataFactory/) | | Core Newtonsoft Json | NuGet [2.0.0](https://www.nuget.org/packages/Microsoft.Azure.Core.NewtonsoftJson/2.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.NewtonsoftJson-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.NewtonsoftJson_2.0.0/sdk/core/Microsoft.Azure.Core.NewtonsoftJson/) | | Core WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.CoreWCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.CoreWCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.CoreWCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.CoreWCF.Azure.StorageQueues/) | @@ -158,7 +158,7 @@ | Functions extension for Storage Queues | NuGet [5.3.7](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/5.3.7) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.Storage.Queues-readme) | GitHub [5.3.7](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.Storage.Queues_5.3.7/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/) | | Functions extension for WebPubSub for SocketIO | NuGet [1.0.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO/1.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO_1.0.0/sdk/webpubsub/Microsoft.Azure.WebJobs.Extensions.WebPubSubForSocketIO/) | | Provisioning - App Configuration | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.AppConfiguration/1.1.0) | [docs](/dotnet/api/overview/azure/Provisioning.AppConfiguration-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppConfiguration_1.1.0/sdk/provisioning/Azure.Provisioning.AppConfiguration/) | -| Provisioning - App Containers | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.AppContainers/1.1.0) | [docs](/dotnet/api/overview/azure/Provisioning.AppContainers-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppContainers_1.1.0/sdk/provisioning/Azure.Provisioning.AppContainers/) | +| Provisioning - App Containers | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.AppContainers/1.1.0)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.Provisioning.AppContainers/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/Provisioning.AppContainers-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppContainers_1.1.0/sdk/provisioning/Azure.Provisioning.AppContainers/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppContainers_1.2.0-beta.1/sdk/provisioning/Azure.Provisioning.AppContainers/) | | Provisioning - App Service | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Provisioning.AppService/1.3.1) | [docs](/dotnet/api/overview/azure/Provisioning.AppService-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.AppService_1.3.1/sdk/provisioning/Azure.Provisioning.AppService/) | | Provisioning - Application Insights | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Provisioning.ApplicationInsights/1.1.0) | [docs](/dotnet/api/overview/azure/Provisioning.ApplicationInsights-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.ApplicationInsights_1.1.0/sdk/provisioning/Azure.Provisioning.ApplicationInsights/) | | Provisioning - Cognitive Services | NuGet [1.2.0](https://www.nuget.org/packages/Azure.Provisioning.CognitiveServices/1.2.0) | [docs](/dotnet/api/overview/azure/Provisioning.CognitiveServices-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Provisioning.CognitiveServices_1.2.0/sdk/provisioning/Azure.Provisioning.CognitiveServices/) | @@ -279,7 +279,7 @@ | Resource Management - Event Hubs | NuGet [1.2.1](https://www.nuget.org/packages/Azure.ResourceManager.EventHubs/1.2.1)
NuGet [1.3.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.EventHubs/1.3.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.EventHubs-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.EventHubs_1.2.1/sdk/eventhub/Azure.ResourceManager.EventHubs/)
GitHub [1.3.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.EventHubs_1.3.0-beta.1/sdk/eventhub/Azure.ResourceManager.EventHubs/) | | Resource Management - Extended Location | NuGet [1.1.1](https://www.nuget.org/packages/Azure.ResourceManager.ExtendedLocations/1.1.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ExtendedLocations-readme) | GitHub [1.1.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ExtendedLocations_1.1.1/sdk/extendedlocation/Azure.ResourceManager.ExtendedLocations/) | | Resource Management - Fabric | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.Fabric/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Fabric-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Fabric_1.0.0/sdk/fabric/Azure.ResourceManager.Fabric/) | -| Resource Management - Fileshares | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.FileShares/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.FileShares-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FileShares_1.0.0-beta.1/sdk/fileshares/Azure.ResourceManager.FileShares/) | +| Resource Management - Fileshares | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.FileShares/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.FileShares-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FileShares_1.0.0-beta.2/sdk/fileshares/Azure.ResourceManager.FileShares/) | | Resource Management - Fluid Relay | NuGet [1.1.1](https://www.nuget.org/packages/Azure.ResourceManager.FluidRelay/1.1.1) | [docs](/dotnet/api/overview/azure/ResourceManager.FluidRelay-readme) | GitHub [1.1.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FluidRelay_1.1.1/sdk/fluidrelay/Azure.ResourceManager.FluidRelay/) | | Resource Management - Front Door | NuGet [1.4.1](https://www.nuget.org/packages/Azure.ResourceManager.FrontDoor/1.4.1) | [docs](/dotnet/api/overview/azure/ResourceManager.FrontDoor-readme) | GitHub [1.4.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.FrontDoor_1.4.1/sdk/frontdoor/Azure.ResourceManager.FrontDoor/) | | Resource Management - Graph Services | NuGet [1.1.2](https://www.nuget.org/packages/Azure.ResourceManager.GraphServices/1.1.2) | [docs](/dotnet/api/overview/azure/ResourceManager.GraphServices-readme) | GitHub [1.1.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.GraphServices_1.1.2/sdk/graphservices/Azure.ResourceManager.GraphServices/) | diff --git a/docs/azure/migration/appmod/includes/quickstart-visual-studio.md b/docs/azure/migration/appmod/includes/quickstart-visual-studio.md new file mode 100644 index 0000000000000..ca92540a6d9d4 --- /dev/null +++ b/docs/azure/migration/appmod/includes/quickstart-visual-studio.md @@ -0,0 +1,98 @@ +--- +ms.topic: include +ms.date: 01/22/2026 +--- + +## Prerequisites + +[!INCLUDE [github-copilot-app-modernization-prereqs](../../../../includes/github-copilot-app-modernization-prereqs.md)] + +## Assess app readiness + +GitHub Copilot app modernization for .NET assessment helps you find app readiness challenges, learn their impact, and see recommended migration tasks. Each migration task includes references to set up Azure resources, add configurations, and make code changes. Follow these steps to start your migration: + +1. Clone the [.NET migration copilot samples](https://github.com/Azure-Samples/dotnet-migration-copilot-samples) repository to your computer. + +1. In Visual Studio, open the **Contoso University** solution from the samples repository. + +1. In Solution Explorer, right-click the solution node and select **Modernize**. + + :::image type="content" source="../media/modernize-solution.png" alt-text="Screenshot that shows the modernize option in the context menu."::: + +1. The GitHub Copilot Chat window opens with a welcome message and predefined options. Select **Migrate to Azure** from the available choices and send it to Copilot. + + :::image type="content" source="../media/modernization-welcome.png" alt-text="Screenshot that shows the welcome message with migration options."::: + + > [!TIP] + > Instead of steps 3 and 4, you can open **GitHub Copilot Chat** directly and send `@Modernize Migrate to Azure` to start the assessment and migration flow. + +1. A new Copilot chat session opens and shows the welcome message. The assessment starts automatically and analyzes your project for migration readiness. + + :::image type="content" source="../media/assessment-in-process.png" alt-text="Screenshot that shows assessment in progress with status indicators."::: + +1. When the assessment finishes, you see a comprehensive assessment report UI page and a list of migration tasks in the chat window. + + :::image type="content" source="../media/assessment-report.png" alt-text="Screenshot that shows the generated assessment report with detailed findings."::: + +## App migrations + +GitHub Copilot app modernization for .NET includes [predefined tasks](../predefined-tasks.md) for common migration scenarios and follows Microsoft's best practices. + +### Start a migration task + +Start a migration task in one of the following ways: + +**Option 1. Run from the Assessment Report** + +Select the **Run Task** button in the Assessment Report from the previous step to start a migration task. + +**Option 2. Send in Copilot Chat** + +Send the migration task number (for example, 1.1) or its name in the chat. + +:::image type="content" source="../media/quickstart-chat-experience.png" alt-text="Screenshot of sending a message in Copilot Chat to start a migration task."::: + +### Plan and progress tracker generation + +- When you start the migration, GitHub Copilot starts a session named "App modernization: migrate from `` to ``" in agent mode with predefined prompts. +- The tool creates two files in the `.appmod/.migration` folder: + - `plan.md`: The overall migration plan. + - `progress.md`: A progress tracker that GitHub Copilot updates as it completes tasks. +- Edit these files to customize your migration before you continue. + +### Start code remediation + +- If you're satisfied with the plan and progress tracker, enter a prompt to start the migration process, such as: + + ```console + The plan and progress tracker look good to me. Go ahead with the migration. + ``` + +- GitHub Copilot starts the migration process and might ask for your approval to use knowledge base tools in the Model Context Protocol (MCP) server. Grant permission when prompted. +- Copilot follows the plan and progress tracker to: + - Manage dependencies. + - Apply configuration changes. + - Make code changes. + - Build the solution, fix all compilation and configuration errors, and ensure a successful build. + - Fix security vulnerabilities. + +## Default chat messages + +GitHub Copilot app modernization for .NET provides default chat message options to streamline your workflow. + +:::image type="content" source="../media/quickstart-followup.png" alt-text="Screenshot that shows default chat message options in the Copilot Chat."::: + +Choose one of the predefined options and send it in the chat: + +- **Run modernization assessment**: Starts a new assessment of your application to identify migration readiness issues and Azure compatibility challenges. +- **View assessment report**: Opens the previous assessment report and shows a summary of migration tasks based on the results. If no previous assessment exists, it runs a new assessment first. +- **Browse top migration tasks**: Shows recommended migration tasks and common modernization scenarios, regardless of any specific assessment results. + +> [!TIP] +> These default messages help you quickly navigate common workflows without typing custom prompts. You can also enter your own messages to interact with Copilot for specific questions or needs. + +## Next steps + +- [Working with assessment](../working-with-assessment.md) +- [Predefined Tasks](../predefined-tasks.md) +- [Frequently Asked Questions](../../../../core/porting/github-copilot-app-modernization/faq.yml) diff --git a/docs/azure/migration/appmod/includes/quickstart-vscode.md b/docs/azure/migration/appmod/includes/quickstart-vscode.md new file mode 100644 index 0000000000000..966c05aa36b52 --- /dev/null +++ b/docs/azure/migration/appmod/includes/quickstart-vscode.md @@ -0,0 +1,124 @@ +--- +ms.topic: include +ms.date: 01/26/2026 +title: GitHub Copilot App Modernization for .NET in VS Code +description: Learn how to assess .NET app readiness and migrate to Azure with GitHub Copilot in Visual Studio Code. Follow step-by-step guidance for seamless modernization. +--- + +## Prerequisites + +- A GitHub account with an active [GitHub Copilot](https://github.com/features/copilot) subscription under any plan. +- The latest version of [Visual Studio Code](https://code.visualstudio.com/). Must be version 1.101 or later. + + - [GitHub Copilot in Visual Studio Code](https://code.visualstudio.com/docs/copilot/overview). For setup instructions, see [Set up GitHub Copilot in VisualStudio Code](https://code.visualstudio.com/docs/copilot/setup). Be sure to sign in to your GitHub account within Visual Studio Code. + - [GitHub Copilot app modernization](https://marketplace.visualstudio.com/items?itemName=vscjava.migrate-java-to-azure). Restart Visual Studio Code afterinstallation. + +- A .NET development environment to build and test the project. + +## Assess app readiness + +GitHub Copilot app modernization for .NET assessment helps you find app readiness challenges, learn their impact, and see recommended migration tasks. Each migration task includes references to set up Azure resources, add configurations, and make code changes. Follow these steps to start your migration: + +1. Clone the [.NET migration copilot samples](https://github.com/Azure-Samples/dotnet-migration-copilot-samples) repository to your computer. + +1. In Visual Studio Code, open the **Contoso University** solution from the samples repository. + +1. Open the **GitHub Copilot app modernization** extension. + +1. In the **QUICKSTART** section, select **Start Assessment**. The **Assessment reports** page opens. + +1. Select **Run Assessment** in the upper-right corner of the page. + + :::image type="content" source="../media/vscode/start-assessment.png" alt-text="Screenshot of run a task in tasks section to start a migration task."::: + +1. The assessment starts automatically and analyzes your project for migration readiness. + + :::image type="content" source="../media/vscode/assessment-in-process.png" alt-text="Screenshot of run a task analyzing your project for migration readiness."::: + +1. When the assessment finishes, you see a comprehensive assessment report UI page and a list of migration tasks in the chat window. + + :::image type="content" source="../media/vscode/assessment-report.png" alt-text="Screenshot of run an assessment report UI page and a list of migration tasks."::: + +## App migrations + +GitHub Copilot app modernization for .NET includes [predefined tasks](../predefined-tasks.md) for common migration scenarios and follows Microsoft's best practices. + +### Chat-based migration (recommended) + +Chat-based migration is the recommended way to start a migration. The `AppModernization-DotNet` custom agent is optimized for application modernization tasks. This agent lets you use simple, natural language prompts to perform complex migration scenarios. + +Complete the following steps to select the custom agent and start the migration: + +1. Make sure you have a .NET project open in Visual Studio Code. + +1. Select the chat icon in the **Activity Bar** to open the Copilot chat window. + +1. In the chat window, locate the agent selector dropdown menu at the top of the chat input box. Select **AppModernization-DotNet** from the list. This custom agent is designed for .NET application modernization and migration scenarios. + + :::image type="content" source="../media/vscode/custom-agent.png" alt-text="Screenshot of selecting the .NET custom agent in the chat window."::: + +1. Enter a prompt using the format `migrate from to ` in the chat window. For example: + + ```text + migrate from rabbitmq to Azure service bus + ``` + +1. The agent analyzes your code, creates a migration plan, makes code changes, runs validations, and generates a summary. Select **Continue** to proceed through each step and **Keep** to accept the changes. + +### Start a migration task from the UI + +You can also start a migration task from the UI: + +**Option 1. Run from the Assessment Report** + +Select the **Run Task** button in the Assessment Report from the previous step to start a migration task. + +**Option 2. Apply a predefined task** + +Run the specific task in the **TASKS - .NET** section. For example, the **Migrate Database to Azure Database for PostgreSQL** task under **Database Tasks** updates your database connection, configurations, dependencies, and data access code to use Azure Database for PostgreSQL. + +:::image type="content" source="../media/vscode/run-task.png" alt-text="Screenshot of running a specific predefined task."::: + +### Plan and progress tracker generation + +When you start the migration, GitHub Copilot starts a session in agent mode. + +The tool creates two files in the `.github/appmod/code-migration/` folder: + +- `plan.md`: The overall migration plan. +- `progress.md`: A progress tracker that GitHub Copilot updates as it completes tasks. + +Edit these files to customize your migration before you continue. + +:::image type="content" source="../media/vscode/start-migration.png" alt-text="Screenshot of plan generation during a migration task."::: + +### Start code remediation + +When you're satisfied with the plan and progress tracker, enter **continue** to start the migration. + +GitHub Copilot starts the migration process and might ask for your approval to use knowledge base tools in the Model Context Protocol (MCP) server. Grant permission when prompted. + +Copilot follows the plan and progress tracker to: + +- Manage dependencies. +- Apply configuration changes. +- Make code changes. +- Build the project, fix all compilation and configuration errors, and ensure a successful build. +- Fix security vulnerabilities. + +Repeatedly select or enter **Continue** to confirm the use of tools or commands and wait for the code changes to finish. + +> [!NOTE] +> In Visual Studio Code, app modernization uses the `AppModernization-DotNet` custom agent with Claude Sonnet 4.5 by default for best results when updating .NET code to migrate to Azure. It falls back to the 'auto' model if Sonnet 4.5 isn't available to you. You can configure the custom agent to [modify the 'model' setting](https://code.visualstudio.com/docs/copilot/customization/custom-agents#_custom-agent-file-structure) by selecting **Configure Custom Agents** from the **Agent** menu. Alternatively, you can use the language model picker in the chat window to switch models for the current chat session. + +### Validation iteration + +After the code changes finish, the migration tool starts a validation and fix iteration loop. This loop includes the following five steps: + +1. Detect Common Vulnerabilities and Exposures (CVEs) in current dependencies and fix them. +1. Build the project and resolve any build errors. +1. Analyze the code for functional consistency. +1. Analyze the project for unit test failures and automatically generate a plan to fix them until the tests pass. +1. Analyze the code for migration items missed in the initial code migration and fix them. + +After all processes complete, the migration tool generates a summary. Review the code changes and confirm them by selecting **Keep**. diff --git a/docs/azure/migration/appmod/media/vscode/assessment-in-process.png b/docs/azure/migration/appmod/media/vscode/assessment-in-process.png new file mode 100644 index 0000000000000..79d209e911a8d Binary files /dev/null and b/docs/azure/migration/appmod/media/vscode/assessment-in-process.png differ diff --git a/docs/azure/migration/appmod/media/vscode/assessment-report.png b/docs/azure/migration/appmod/media/vscode/assessment-report.png new file mode 100644 index 0000000000000..b898776ce93e9 Binary files /dev/null and b/docs/azure/migration/appmod/media/vscode/assessment-report.png differ diff --git a/docs/azure/migration/appmod/media/vscode/custom-agent.png b/docs/azure/migration/appmod/media/vscode/custom-agent.png new file mode 100644 index 0000000000000..2414944300577 Binary files /dev/null and b/docs/azure/migration/appmod/media/vscode/custom-agent.png differ diff --git a/docs/azure/migration/appmod/media/vscode/run-task.png b/docs/azure/migration/appmod/media/vscode/run-task.png new file mode 100644 index 0000000000000..644d8664d53ff Binary files /dev/null and b/docs/azure/migration/appmod/media/vscode/run-task.png differ diff --git a/docs/azure/migration/appmod/media/vscode/start-assessment.png b/docs/azure/migration/appmod/media/vscode/start-assessment.png new file mode 100644 index 0000000000000..eecc2d2e80afe Binary files /dev/null and b/docs/azure/migration/appmod/media/vscode/start-assessment.png differ diff --git a/docs/azure/migration/appmod/media/vscode/start-migration.png b/docs/azure/migration/appmod/media/vscode/start-migration.png new file mode 100644 index 0000000000000..f85fbe1dac6c8 Binary files /dev/null and b/docs/azure/migration/appmod/media/vscode/start-migration.png differ diff --git a/docs/azure/migration/appmod/quickstart.md b/docs/azure/migration/appmod/quickstart.md index 112ed94de3c9f..ca7cdc6762790 100644 --- a/docs/azure/migration/appmod/quickstart.md +++ b/docs/azure/migration/appmod/quickstart.md @@ -1,10 +1,11 @@ --- title: Assess and migrate a .NET project with GitHub Copilot app modernization for .NET ms.reviewer: alexwolf -description: Learn how to assess and migrate a .NET project by using GitHub Copilot app modernization for .NET. +description: Assess and migrate your .NET project with GitHub Copilot. Learn how to evaluate migration readiness and start modernizing your app effectively. ms.topic: quickstart ms.custom: devx-track-dotnet -ms.date: 09/22/2025 +ms.date: 01/26/2026 +zone_pivot_groups: ide-set-one #customer intent: As a .NET developer, I want to assess my project's migration readiness so that I can identify potential challenges and plan the modernization process effectively. --- @@ -15,96 +16,15 @@ In this quickstart, you assess and migrate a .NET project by using GitHub Copilo - Assess a sample project (Contoso University) - Start the migration process -## Prerequisites +::: zone pivot="visualstudio" +[!INCLUDE [quickstart-visual-studio](./includes/quickstart-visual-studio.md)] +::: zone-end -[!INCLUDE [github-copilot-app-modernization-prereqs](../../../includes/github-copilot-app-modernization-prereqs.md)] - -## Assess app readiness - -GitHub Copilot app modernization for .NET assessment helps you find app readiness challenges, learn their impact, and see recommended migration tasks. Each migration task includes references to set up Azure resources, add configurations, and make code changes. Follow these steps to start your migration: - -1. Clone the [.NET migration copilot samples](https://github.com/Azure-Samples/dotnet-migration-copilot-samples) repository to your computer. - -1. In Visual Studio, open the **Contoso University** solution from the samples repository. - -1. In Solution Explorer, right-click the solution node and select **Modernize**. - - :::image type="content" source="media/modernize-solution.png" alt-text="Screenshot that shows the modernize option in the context menu."::: - -1. The GitHub Copilot Chat window opens with a welcome message and predefined options. Select **Migrate to Azure** from the available choices and send it to Copilot. - - :::image type="content" source="media/modernization-welcome.png" alt-text="Screenshot that shows the welcome message with migration options."::: - - > [!TIP] - > Instead of steps 3 and 4, you can open **GitHub Copilot Chat** directly and send `@Modernize Migrate to Azure` to start the assessment and migration flow. - -1. A new Copilot chat session opens and shows the welcome message. The assessment starts automatically and analyzes your project for migration readiness. - - :::image type="content" source="media/assessment-in-process.png" alt-text="Screenshot that shows assessment in progress with status indicators."::: - -1. When the assessment finishes, you see a comprehensive assessment report UI page and a list of migration tasks in the chat window. - - :::image type="content" source="media/assessment-report.png" alt-text="Screenshot that shows the generated assessment report with detailed findings."::: - -## App migrations - -GitHub Copilot app modernization for .NET includes [predefined tasks](predefined-tasks.md) for common migration scenarios and follows Microsoft's best practices. - -### Start a migration task - -Start a migration task in one of the following ways: - -**Option 1. Run from the Assessment Report** - -Select the **Run Task** button in the Assessment Report from the previous step to start a migration task. - -**Option 2. Send in Copilot Chat** - -Send the migration task number (for example, 1.1) or its name in the chat. - -:::image type="content" source="media/quickstart-chat-experience.png" alt-text="Screenshot of sending a message in Copilot Chat to start a migration task."::: - -### Plan and progress tracker generation - -- When you start the migration, GitHub Copilot starts a session named "App modernization: migrate from `` to ``" in agent mode with predefined prompts. -- The tool creates two files in the `.appmod/.migration` folder: - - `plan.md` - the overall migration plan - - `progress.md` - a progress tracker; GitHub Copilot marks items as it completes tasks -- Edit these files to customize your migration before you continue. - -### Start code remediation - -- If you're satisfied with the plan and progress tracker, enter a prompt to start the migration, such as: - - ```console - The plan and progress tracker look good to me. Go ahead with the migration. - ``` - -- GitHub Copilot starts the migration process and might ask for your approval to use knowledge base tools in the Model Context Protocol (MCP) server. Grant permission when prompted. -- Copilot follows the plan and progress tracker to: - - Manage dependencies - - Apply configuration changes - - Make code changes - - Build the solution, fix all compilation and configuration errors, and ensure a successful build - - Fix security vulnerabilities - -## Default chat messages - -GitHub Copilot app modernization for .NET gives you default chat message options to streamline your workflow. - -:::image type="content" source="media/quickstart-followup.png" alt-text="Screenshot that shows default chat message options in the Copilot Chat."::: - -You can choose one of the predefined options and send it in the chat: - -- **Run modernization assessment**: Starts a new assessment of your application to identify migration readiness issues and Azure compatibility challenges. -- **View assessment report**: Opens the previous assessment report and shows a summary of migration tasks based on the results. If no previous assessment exists, it runs a new assessment first. -- **Browse top migration tasks**: Shows recommended migration tasks and common modernization scenarios, regardless of any specific assessment results. - -> [!TIP] -> These default messages help you quickly navigate common workflows without typing custom prompts. You can also enter your own messages to interact with Copilot for specific questions or needs. +::: zone pivot="vscode" +[!INCLUDE [quickstart-vscode](./includes/quickstart-vscode.md)] +::: zone-end ## Next Steps -- [Working with assessment](working-with-assessment.md) - [Predefined Tasks](predefined-tasks.md) -- [Frequently Asked Questions](../../../core/porting/github-copilot-app-modernization/faq.yml) +- [GitHub Copilot app modernization FAQ](../../../core/porting/github-copilot-app-modernization/faq.yml) diff --git a/docs/core/deploying/runtime-store.md b/docs/core/deploying/runtime-store.md index e87ec2b9cf1a1..45446031017f1 100644 --- a/docs/core/deploying/runtime-store.md +++ b/docs/core/deploying/runtime-store.md @@ -1,11 +1,15 @@ --- title: Runtime package store description: Learn how to use the runtime package store to target manifests used by .NET Core. -ms.date: 08/12/2017 +ms.date: 01/29/2026 +ai-usage: ai-assisted --- # Runtime package store -Starting with .NET Core 2.0, it's possible to package and deploy apps against a known set of packages that exist in the target environment. The benefits are faster deployments, lower disk space usage, and improved startup performance in some cases. +> [!WARNING] +> The runtime package store feature is **no longer supported or under active development**. While the `dotnet store` command still exists, it has known issues with .NET 6 and later versions, and **it is not recommended for use**. The .NET team plans to eventually stop shipping this command altogether. For more information, see [GitHub issue #24752](https://github.com/dotnet/sdk/issues/24752). + +Starting with .NET Core 2.0, it was possible to package and deploy apps against a known set of packages that exist in the target environment. The intended benefits were faster deployments, lower disk space usage, and improved startup performance in some cases. However, this feature is now deprecated. This feature is implemented as a *runtime package store*, which is a directory on disk where packages are stored (typically at */usr/local/share/dotnet/store* on macOS/Linux and *C:/Program Files/dotnet/store* on Windows). Under this directory, there are subdirectories for architectures and [target frameworks](../../standard/frameworks.md). The file layout is similar to the way that [NuGet assets are laid out on disk](/nuget/create-packages/supporting-multiple-target-frameworks#framework-version-folder-structure): @@ -54,6 +58,9 @@ The following example package store manifest (*packages.csproj*) is used to add ``` +> [!WARNING] +> The following commands might fail on .NET 6 and later versions due to missing crossgen dependencies. Even with the `--skip-optimization` workaround, the generated manifests might not work correctly. + Provision the runtime package store by executing `dotnet store` with the package store manifest, runtime, and framework: ```dotnetcli @@ -66,6 +73,14 @@ dotnet store --manifest --runtime - dotnet store --manifest packages.csproj --runtime win-x64 --framework netcoreapp2.0 --framework-version 2.0.0 ``` +**Workaround for .NET 6+ (not recommended)** + +If you must use this deprecated feature with .NET 6 or later, you can try adding the `--skip-optimization` flag, although this might not work reliably: + +```dotnetcli +dotnet store --manifest packages.csproj --runtime win-x64 --framework net6.0 --skip-optimization +``` + You can pass multiple target package store manifest paths to a single [`dotnet store`](../tools/dotnet-store.md) command by repeating the option and path in the command. By default, the output of the command is a package store under the *.dotnet/store* subdirectory of the user's profile. You can specify a different location using the `--output ` option. The root directory of the store contains a target manifest *artifact.xml* file. This file can be made available for download and be used by app authors who want to target this store when publishing. @@ -84,6 +99,9 @@ The following *artifact.xml* file is produced after running the previous example ## Publishing an app against a target manifest +> [!CAUTION] +> Publishing against target manifests created with the deprecated runtime package store might fail or behave unexpectedly, especially with .NET 6 and later versions. + If you have a target manifest file on disk, you specify the path to the file when publishing your app with the [`dotnet publish`](../tools/dotnet-publish.md) command: ```dotnetcli @@ -118,9 +136,12 @@ An alternative to specifying target manifests with the [`dotnet publish`](../too Specify the target manifests in the project file only when the target environment for the app is well-known, such as for .NET Core projects. This isn't the case for open-source projects. The users of an open-source project typically deploy it to different production environments. These production environments generally have different sets of packages pre-installed. You can't make assumptions about the target manifest in such environments, so you should use the `--manifest` option of [`dotnet publish`](../tools/dotnet-publish.md). -## ASP.NET Core implicit store (.NET Core 2.0 only) +## ASP.NET Core implicit store (.NET Core 2.0, legacy) + +> [!NOTE] +> This section describes legacy functionality that only applied to .NET Core 2.0. This feature is no longer relevant for modern .NET applications. -The ASP.NET Core implicit store applies only to ASP.NET Core 2.0. We strongly recommend applications use ASP.NET Core 2.1 and later, which does **not** use the implicit store. ASP.NET Core 2.1 and later use the shared framework. +The ASP.NET Core implicit store applied only to ASP.NET Core 2.0. We strongly recommend applications use ASP.NET Core 2.1 and later, which does **not** use the implicit store. ASP.NET Core 2.1 and later use the shared framework. For .NET Core 2.0, the runtime package store feature is used implicitly by an ASP.NET Core app when the app is deployed as a [framework-dependent deployment](index.md#framework-dependent-deployment) app. The targets in [`Microsoft.NET.Sdk.Web`](https://github.com/aspnet/websdk) include manifests referencing the implicit package store on the target system. Additionally, any framework-dependent app that depends on the `Microsoft.AspNetCore.All` package results in a published app that contains only the app and its assets and not the packages listed in the `Microsoft.AspNetCore.All` metapackage. It's assumed that those packages are present on the target system. @@ -141,3 +162,4 @@ When deploying a [framework-dependent deployment](index.md#framework-dependent-d - [dotnet-publish](../tools/dotnet-publish.md) - [dotnet-store](../tools/dotnet-store.md) +- [GitHub issue: 'dotnet store' can't find crossgen with .NET 6](https://github.com/dotnet/sdk/issues/24752) diff --git a/docs/core/extensions/logging/custom-provider.md b/docs/core/extensions/logging/custom-provider.md index ab770f44b7be3..0aeb14fbf06fb 100644 --- a/docs/core/extensions/logging/custom-provider.md +++ b/docs/core/extensions/logging/custom-provider.md @@ -1,44 +1,41 @@ --- title: Implement a custom logging provider description: Discover how to implement a custom logging provider with colorized logs, writing custom C# ILogger and ILoggerProvider implementations. -ms.date: 10/20/2025 +ms.date: 02/04/2026 ms.topic: how-to --- # Implement a custom logging provider in .NET -There are many [logging providers](providers.md) available for common logging needs. You might need to implement a custom when one of the available providers doesn't suit your application needs. In this article, you learn how to implement a custom logging provider that can be used to colorize logs in the console. +There are many [logging providers](providers.md) available for common logging needs. But you might need to implement a custom when one of the available providers doesn't suit your application needs. In this article, you learn how to implement a custom logging provider that can be used to colorize logs in the console. > [!TIP] -> The custom logging provider example source code is available in the **Docs GitHub repo**. For more information, see [GitHub: .NET Docs - Console Custom Logging](https://github.com/dotnet/docs/tree/main/docs/core/extensions/snippets/configuration/console-custom-logging). +> The custom logging provider example source code is available in the [docs GitHub repo](https://github.com/dotnet/docs/tree/main/docs/core/extensions/snippets/configuration/console-custom-logging). -### Sample custom logger configuration +## Sample custom logger configuration -The sample creates different color console entries per log level and event ID using the following configuration type: +The sample logger creates different color console entries per log level and event ID using the following configuration type: :::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLoggerConfiguration.cs"::: -The preceding code sets the default level to `Information`, the color to `Green`, and the `EventId` is implicitly `0`. +The preceding code sets the default color for the `Information` level to `Green`. The `EventId` is implicitly 0. -### Create the custom logger +## Create the custom logger -The `ILogger` implementation category name is typically the logging source. For example, the type where the logger is created: +The following code snippet shows the `ILogger` implementation: :::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLogger.cs"::: -The preceding code: +Each logger instance is instantiated by passing a category name, which is typically the type where the logger is created. The `IsEnabled` method checks `getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)` to see if the requested log level is enabled (that is, in the configuration's dictionary of log levels). -- Creates a logger instance per category name. -- Checks `_getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)` in `IsEnabled`, so each `logLevel` has a unique logger. In this implementation, each log level requires an explicit configuration entry to log. +It's a good practice to call within implementations since `Log` can be called by any consumer, and there are no guarantees that it was previously checked. The `IsEnabled` method should be very fast in most implementations. -It's a good practice to call within implementations since `Log` can be called by any consumer, and there are no guarantees that it was previously checked. The `IsEnabled` method should be very fast in most implementations. +:::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLogger.cs" range="20-23"::: -:::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLogger.cs" range="15-16"::: - -The logger is instantiated with the `name` and a `Func`, which returns the current config—this handles updates to the config values as monitored through the callback. +The logger is instantiated with the `name` and a `Func` that returns the current configuration. > [!IMPORTANT] -> The implementation checks if the `config.EventId` value is set. When `config.EventId` is not set or when it matches the exact `logEntry.EventId`, the logger logs in color. +> The implementation checks if the `config.EventId` value is set. When `config.EventId` is not set or when it matches the exact `logEntry.EventId`, the logger logs in color. ## Custom logger provider @@ -46,13 +43,11 @@ The `ILoggerProvider` object is responsible for creating logger instances. It's :::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLoggerProvider.cs"::: -In the preceding code, creates a single instance of the `ColorConsoleLogger` per category name and stores it in the [`ConcurrentDictionary`](/dotnet/api/system.collections.concurrent.concurrentdictionary-2). Additionally, the interface is required to update changes to the underlying `ColorConsoleLoggerConfiguration` object. - -To control the configuration of the `ColorConsoleLogger`, you define an alias on its provider: +In the preceding code, creates a single instance of the `ColorConsoleLogger` per category name and stores it in the [`ConcurrentDictionary`](/dotnet/api/system.collections.concurrent.concurrentdictionary-2). -:::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLoggerProvider.cs" range="6-8" highlight="6-7"::: +The `ColorConsoleLoggerProvider` class is decorated with two attributes: -The `ColorConsoleLoggerProvider` class defines two class-scoped attributes: +:::code language="csharp" source="../snippets/configuration/console-custom-logging/ColorConsoleLoggerProvider.cs" range="6-8"::: - : The `ColorConsoleLogger` type is _not supported_ in the `"browser"`. - : Configuration sections can define options using the `"ColorConsole"` key. @@ -61,34 +56,25 @@ The configuration can be specified with any valid [configuration provider](../co :::code language="json" source="../snippets/configuration/console-custom-logging/appsettings.json"::: -This configures the log levels to the following values: - -- : -- : -- : - -The log level is set to , which overrides the default value set in the `ColorConsoleLoggerConfiguration` object. +The _appsettings.json_ file specifies that the color for the log level is , which overrides the default value set in the `ColorConsoleLoggerConfiguration` object. ## Usage and registration of the custom logger -By convention, registering services for dependency injection happens as part of the startup routine of an application. The registration occurs in the `Program` class, or could be delegated to a `Startup` class. In this example, you'll register directly from the _Program.cs_. - -To add the custom logging provider and corresponding logger, add an with from the : +By convention, services are registered for dependency injection as part of the startup routine of an application. In this example, the logging service is registered directly from the _Program.cs_ file. -:::code language="csharp" source="../snippets/configuration/console-custom-logging/Program.cs" highlight="6-14"::: +To add the custom logging provider and corresponding logger, add an by calling a custom extension method, `AddColorConsoleLogger`, on the from the property: -The `ILoggingBuilder` creates one or more `ILogger` instances. The `ILogger` instances are used by the framework to log the information. - -The configuration from the _appsettings.json_ file overrides the following values: - -- : -- : +:::code language="csharp" source="../snippets/configuration/console-custom-logging/Program.cs" highlight="8-16"::: By convention, extension methods on `ILoggingBuilder` are used to register the custom provider: :::code language="csharp" source="../snippets/configuration/console-custom-logging/Extensions/ColorConsoleLoggerExtensions.cs"::: -Running this simple application will render color output to the console window similar to the following image: +The `ILoggingBuilder` creates one or more `ILogger` instances. The `ILogger` instances are used by the framework to log the information. + +The instantiation code overrides the color values from the _appsettings.json_ file for and . + +When you run this simple app, it renders color output to the console window similar to the following image: :::image type="content" source="media/color-console-logger.png" alt-text="Color console logger sample output"::: diff --git a/docs/core/extensions/service-discovery.md b/docs/core/extensions/service-discovery.md index 9660e735a1893..fa1dbb4ead697 100644 --- a/docs/core/extensions/service-discovery.md +++ b/docs/core/extensions/service-discovery.md @@ -116,12 +116,12 @@ The configuration resolver is configured using the extension method on the `IServiceCollection` within your application's `Startup` class or `Program` file: ```csharp var builder = WebApplication.CreateBuilder(args); -builder.Services.Configure( +builder.Services.Configure( static options => { options.SectionName = "MyServiceEndpoints"; diff --git a/docs/core/extensions/snippets/configuration/console-custom-logging/ColorConsoleLogger.cs b/docs/core/extensions/snippets/configuration/console-custom-logging/ColorConsoleLogger.cs index a7884c99d7530..df51ad49e026d 100644 --- a/docs/core/extensions/snippets/configuration/console-custom-logging/ColorConsoleLogger.cs +++ b/docs/core/extensions/snippets/configuration/console-custom-logging/ColorConsoleLogger.cs @@ -4,7 +4,8 @@ public sealed class ColorConsoleLogger( string name, Func getCurrentConfig) : ILogger { - public IDisposable? BeginScope(TState state) where TState : notnull => default!; + public IDisposable? BeginScope(TState state) + where TState : notnull => default!; public bool IsEnabled(LogLevel logLevel) => getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel); diff --git a/docs/core/extensions/snippets/configuration/console-custom-logging/Program.cs b/docs/core/extensions/snippets/configuration/console-custom-logging/Program.cs index 6f79ee3f22a62..e2d74fa7eb2a8 100644 --- a/docs/core/extensions/snippets/configuration/console-custom-logging/Program.cs +++ b/docs/core/extensions/snippets/configuration/console-custom-logging/Program.cs @@ -7,15 +7,17 @@ builder.Logging.ClearProviders(); builder.Logging.AddColorConsoleLogger(configuration => { - // Replace warning value from appsettings.json of "Cyan" - configuration.LogLevelToColorMap[LogLevel.Warning] = ConsoleColor.DarkCyan; - // Replace warning value from appsettings.json of "Red" - configuration.LogLevelToColorMap[LogLevel.Error] = ConsoleColor.DarkRed; + // Replace value of "Cyan" from appsettings.json. + configuration.LogLevelToColorMap[LogLevel.Warning] + = ConsoleColor.DarkCyan; + // Replace value of "Red" from appsettings.json. + configuration.LogLevelToColorMap[LogLevel.Error] + = ConsoleColor.DarkRed; }); using IHost host = builder.Build(); -var logger = host.Services.GetRequiredService>(); +ILogger logger = host.Services.GetRequiredService>(); logger.LogDebug(1, "Does this line get hit?"); // Not logged logger.LogInformation(3, "Nothing to see here."); // Logs in ConsoleColor.DarkGreen diff --git a/docs/core/testing/microsoft-testing-platform-intro.md b/docs/core/testing/microsoft-testing-platform-intro.md index 1a47b70895f54..67a6246c82ff2 100644 --- a/docs/core/testing/microsoft-testing-platform-intro.md +++ b/docs/core/testing/microsoft-testing-platform-intro.md @@ -43,6 +43,10 @@ The main driving factors for the evolution of the new testing platform are detai * xUnit.net. For more information, see [Microsoft Testing Platform (xUnit.net v3)](https://xunit.net/docs/getting-started/v3/microsoft-testing-platform) and [Microsoft Testing Platform (xUnit.net v2)](https://xunit.net/docs/getting-started/v2/microsoft-testing-platform) from the xUnit.net documentation. * TUnit: entirely constructed on top of the `Microsoft.Testing.Platform`, for more information, see [TUnit documentation](https://tunit.dev/). +## Supported target frameworks + +Microsoft.Testing.Platform supports .NET (.NET 8 SDK and later), .NET Framework (versions 4.6.2 and later), and targets NETStandard 2.0 for maximum compatibility with other runtimes. + ## Run and debug tests `Microsoft.Testing.Platform` test projects are built as executables that can be run (or debugged) directly. There's no extra test running console or command. The app exits with a nonzero exit code if there's an error, which is typical for most executables. For more information on the known exit codes, see [Microsoft.Testing.Platform exit codes](microsoft-testing-platform-exit-codes.md). diff --git a/docs/core/tools/dotnet-store.md b/docs/core/tools/dotnet-store.md index 74a988725b682..9d1c937baacda 100644 --- a/docs/core/tools/dotnet-store.md +++ b/docs/core/tools/dotnet-store.md @@ -1,12 +1,16 @@ --- title: dotnet store command description: The 'dotnet store' command stores the specified assemblies in the runtime package store. -ms.date: 09/29/2025 +ms.date: 02/04/2026 +ai-usage: ai-assisted --- # dotnet store **This article applies to:** ✔️ .NET 6 SDK and later versions +> [!WARNING] +> The `dotnet store` command and the runtime package store feature are **deprecated and no longer supported**. This command has known issues with .NET 6 and later versions and **is not recommended for use**. The .NET team plans to eventually stop shipping this command. For more information, see [GitHub issue #24752](https://github.com/dotnet/sdk/issues/24752). + ## Name `dotnet store` - Stores the specified assemblies in the [runtime package store](../deploying/runtime-store.md). @@ -27,6 +31,9 @@ dotnet store -h|--help ## Description +> [!CAUTION] +> The runtime package store feature is deprecated and no longer functional on .NET 6+. This command might fail with crossgen-related errors. Even when using the `--skip-optimization` workaround, the generated stores might not work correctly. + `dotnet store` stores the specified assemblies in the [runtime package store](../deploying/runtime-store.md). By default, assemblies are optimized for the target runtime and framework. For more information, see the [runtime package store](../deploying/runtime-store.md) topic. ## Required options diff --git a/docs/core/tutorials/creating-app-with-plugin-support.md b/docs/core/tutorials/creating-app-with-plugin-support.md index 5c5dab5a27b49..888d8d1dd1d62 100644 --- a/docs/core/tutorials/creating-app-with-plugin-support.md +++ b/docs/core/tutorials/creating-app-with-plugin-support.md @@ -3,7 +3,7 @@ title: Create a .NET Core application with plugins description: Learn how to create a .NET Core application that supports plugins. author: jkoritzinsky ms.author: jekoritz -ms.date: 11/20/2024 +ms.date: 02/04/2026 --- # Create a .NET Core application with plugins @@ -81,6 +81,13 @@ namespace AppWithPlugin { Console.WriteLine($"-- {commandName} --"); + // Skip command-line switches/flags (arguments starting with '/' or '-') + if (commandName.StartsWith("/") || commandName.StartsWith("-")) + { + Console.WriteLine($"Skipping command-line flag: {commandName}"); + continue; + } + // Execute the command with the name passed as an argument. Console.WriteLine(); @@ -138,8 +145,8 @@ Replace the `// Execute the command with the name passed as an argument` comment ICommand command = commands.FirstOrDefault(c => c.Name == commandName); if (command == null) { - Console.WriteLine("No such command is known."); - return; + Console.WriteLine($"No such command is known: {commandName}"); + continue; } command.Execute(); @@ -228,7 +235,9 @@ Now, open the *HelloPlugin.csproj* file. It should look similar to the following - net5.0 + net10.0 + enable + enable @@ -258,7 +267,7 @@ The `false` element is important. This tells MSBuild to not c Similarly, the `runtime` element is also important if the `PluginBase` references other packages. This setting has the same effect as `false` but works on package references that the `PluginBase` project or one of its dependencies may include. -Now that the `HelloPlugin` project is complete, you should update the `AppWithPlugin` project to know where the `HelloPlugin` plugin can be found. After the `// Paths to plugins to load` comment, add `@"HelloPlugin\bin\Debug\net5.0\HelloPlugin.dll"` (this path could be different based on the .NET Core version you use) as an element of the `pluginPaths` array. +Now that the `HelloPlugin` project is complete, you should update the `AppWithPlugin` project to know where the `HelloPlugin` plugin can be found. After the `// Paths to plugins to load` comment, add `@"HelloPlugin\bin\Debug\net10.0\HelloPlugin.dll"` (this path could be different based on the .NET Core version you use) as an element of the `pluginPaths` array. ## Plugin with library dependencies @@ -284,7 +293,7 @@ This prevents the `A.PluginBase` assemblies from being copied to the output dire ## Plugin target framework recommendations -Because plugin dependency loading uses the *.deps.json* file, there is a gotcha related to the plugin's target framework. Specifically, your plugins should target a runtime, such as .NET 5, instead of a version of .NET Standard. The *.deps.json* file is generated based on which framework the project targets, and since many .NET Standard-compatible packages ship reference assemblies for building against .NET Standard and implementation assemblies for specific runtimes, the *.deps.json* may not correctly see implementation assemblies, or it may grab the .NET Standard version of an assembly instead of the .NET Core version you expect. +Because plugin dependency loading uses the *.deps.json* file, there is a gotcha related to the plugin's target framework. Specifically, your plugins should target a runtime, such as .NET 10, instead of a version of .NET Standard. The *.deps.json* file is generated based on which framework the project targets, and since many .NET Standard-compatible packages ship reference assemblies for building against .NET Standard and implementation assemblies for specific runtimes, the *.deps.json* may not correctly see implementation assemblies, or it may grab the .NET Standard version of an assembly instead of the .NET Core version you expect. ## Plugin framework references diff --git a/docs/csharp/language-reference/compiler-messages/array-declaration-errors.md b/docs/csharp/language-reference/compiler-messages/array-declaration-errors.md index 51fc3bac11d09..2c68bd0cddc8a 100644 --- a/docs/csharp/language-reference/compiler-messages/array-declaration-errors.md +++ b/docs/csharp/language-reference/compiler-messages/array-declaration-errors.md @@ -43,6 +43,12 @@ f1_keywords: - "CS9215" - "CS9222" - "CS9332" + - "CS9354" + - "CS9355" + - "CS9356" + - "CS9357" + - "CS9358" + - "CS9359" helpviewer_keywords: - "CS0022" - "CS0178" @@ -85,7 +91,13 @@ helpviewer_keywords: - "CS9215" - "CS9222" - "CS9332" -ms.date: 11/07/2025 + - "CS9354" + - "CS9355" + - "CS9356" + - "CS9357" + - "CS9358" + - "CS9359" +ms.date: 02/04/2026 ai-usage: ai-assisted --- # Resolve errors and warnings in array and collection declarations and initialization expressions @@ -129,6 +141,12 @@ That's by design. The text closely matches the text of the compiler error / warn - [**CS9215**](#invalid-collection-initializer): *Collection expression type 'type' must have an instance or extension method 'Add' that can be called with a single argument.* - [**CS9222**](#invalid-collection-initializer): *Collection initializer results in an infinite chain of instantiations of collection 'type'.* - [**CS9332**](#invalid-collection-initializer): *Cannot use '..' spread operator in the filter expression of a catch clause.* +- [**CS9354**](#invalid-collection-initializer): *'with(...)' element must be the first element* +- [**CS9355**](#invalid-collection-initializer): *'with(...)' elements are not supported for type 'type'* +- [**CS9356**](#invalid-collection-initializer): *'with(...)' element arguments cannot be dynamic* +- [**CS9357**](#invalid-collection-initializer): *'with(...)' element for a read-only interface must be empty if present* +- [**CS9358**](#invalid-collection-initializer): *Element type of this collection may not be a ref struct or a type parameter allowing ref structs* +- [**CS9359**](#invalid-collection-initializer): *No overload for method 'method' takes 'number' 'with(...)' element arguments* In addition, the following warnings are covered in this article: @@ -171,6 +189,12 @@ To access array elements correctly, follow these indexing rules. For more inform - **CS9215**: *Collection expression type 'type' must have an instance or extension method 'Add' that can be called with a single argument.* - **CS9222**: *Collection initializer results in an infinite chain of instantiations of collection 'type'.* - **CS9332**: *Cannot use '..' spread operator in the filter expression of a catch clause.* +- **CS9354**: *'with(...)' element must be the first element* +- **CS9355**: *'with(...)' elements are not supported for type 'type'* +- **CS9356**: *'with(...)' element arguments cannot be dynamic* +- **CS9357**: *'with(...)' element for a read-only interface must be empty if present* +- **CS9358**: *Element type of this collection may not be a ref struct or a type parameter allowing ref structs* +- **CS9359**: *No overload for method 'method' takes 'number' 'with(...)' element arguments* The compiler might also generate the following warnings: @@ -195,6 +219,12 @@ To create valid collection initializers, follow these rules. For more informatio - Implement enumeration patterns (like `GetEnumerator`) for spread operator support (**CS9212**). - Avoid circular dependencies in collection initialization (**CS9222**). - Don't use the spread operator in catch clause filter expressions (**CS9332**). +- Place the `with(...)` element first in collection expressions (**CS9354**). +- Use `with(...)` elements only with types that support collection expression arguments (**CS9355**). +- Don't use dynamic arguments in `with(...)` elements (**CS9356**). +- Use empty `with()` for read-only interface types (**CS9357**). +- Don't use ref struct types as element types in collections that don't support them (**CS9358**). +- Match the number of `with(...)` arguments to available constructor overloads (**CS9359**). ## Invalid array rank diff --git a/docs/csharp/language-reference/compiler-messages/overloaded-operator-errors.md b/docs/csharp/language-reference/compiler-messages/overloaded-operator-errors.md index 3815b8d86829f..21fe0f63d72ed 100644 --- a/docs/csharp/language-reference/compiler-messages/overloaded-operator-errors.md +++ b/docs/csharp/language-reference/compiler-messages/overloaded-operator-errors.md @@ -27,8 +27,6 @@ f1_keywords: - "CS0715" - "CS1037" - "CS1553" - - "CS8930" - - "CS8931" - "CS9023" - "CS9024" - "CS9025" @@ -66,8 +64,6 @@ helpviewer_keywords: - "CS0715" - "CS1037" - "CS1553" - - "CS8930" - - "CS8931" - "CS9023" - "CS9024" - "CS9025" @@ -115,8 +111,8 @@ That's by design. The text closely matches the text of the compiler error / warn - [**CS0715**](#operator-declaration-requirements): *Static classes cannot contain user-defined operators* - [**CS1037**](#operator-declaration-requirements): *Overloadable operator expected* - [**CS1553**](#operator-declaration-requirements): *Declaration is not valid; use 'modifier operator \ (...' instead* -- [**CS8930**](#operator-declaration-requirements): *Explicit implementation of a user-defined operator must be static.* -- [**CS8931**](#operator-declaration-requirements): *Explicit implementation must be declared public to implement interface member in type.* +- [**CS8930**](static-abstract-interfaces.md#errors-in-type-implementing-interface-declaration): *Explicit implementation of a user-defined operator must be declared static* +- [**CS8931**](static-abstract-interfaces.md#errors-in-interface-declaration): *User-defined conversion in an interface must convert to or from a type parameter on the enclosing type constrained to the enclosing type* - [**CS9023**](#checked-operators): *Operator cannot be made checked.* - [**CS9024**](#checked-operators): *Operator cannot be made unchecked.* - [**CS9025**](#checked-operators): *Operator requires a matching non-checked version to also be declared.* @@ -207,8 +203,6 @@ public class C6 - **CS0715**: *Static classes can't contain user-defined operators.* - **CS1037**: *Overloadable operator expected.* - **CS1553**: *Declaration isn't valid; use 'modifier operator \ (...' instead.* -- **CS8930**: *Explicit implementation of a user-defined operator must be static.* -- **CS8931**: *Explicit implementation must be declared public to implement interface member in type.* - **CS9308**: *User-defined operator must be declared public.* To declare operators correctly, follow these requirements for modifiers and containing types. For more information, see [Operator overloading](../operators/operator-overloading.md) and [User-defined conversion operators](../operators/user-defined-conversion-operators.md). @@ -217,7 +211,8 @@ To declare operators correctly, follow these requirements for modifiers and cont - Don't declare operators in static classes (**CS0715**). Use regular classes or structs. - Use valid, overloadable operator symbols (**CS1037**). - Follow the correct syntax for conversion operators: `public static implicit/explicit operator ( parameter)` (**CS1553**). -- Ensure explicit interface implementations of operators are `static` (**CS8930**) and `public` (**CS8931**). + +For errors related to explicit interface implementations of operators in static abstract interfaces, see [Static abstract and virtual interface member errors](static-abstract-interfaces.md#errors-in-type-implementing-interface-declaration). The following example demonstrates declaration errors: diff --git a/docs/csharp/language-reference/compiler-messages/static-abstract-interfaces.md b/docs/csharp/language-reference/compiler-messages/static-abstract-interfaces.md index 114aa243c2dfe..4a29d942e91be 100644 --- a/docs/csharp/language-reference/compiler-messages/static-abstract-interfaces.md +++ b/docs/csharp/language-reference/compiler-messages/static-abstract-interfaces.md @@ -13,6 +13,8 @@ f1_keywords: - "CS9030" - "CS8931" - "CS8932" + - "CS9044" + - "CS9046" helpviewer_keywords: - "CS8920" - "CS8921" @@ -25,7 +27,9 @@ helpviewer_keywords: - "CS8930" - "CS8931" - "CS8932" -ms.date: 11/29/2023 + - "CS9044" + - "CS9046" +ms.date: 02/06/2026 --- # Static abstract and virtual interface member errors and warnings @@ -45,6 +49,8 @@ That's be design. The text closely matches the text of the compiler error / warn - [**CS8930**](#errors-in-type-implementing-interface-declaration): *Explicit implementation of a user-defined operator must be declared static* - [**CS8931**](#errors-in-interface-declaration): *User-defined conversion in an interface must convert to or from a type parameter on the enclosing type constrained to the enclosing type* - [**CS8932**](#errors-in-type-implementing-interface-declaration): *'UnmanagedCallersOnly' method cannot implement interface member in type* +- [**CS9044**](#errors-in-type-implementing-interface-declaration): *Type does not implement interface member. Method cannot implicitly implement an inaccessible member.* +- [**CS9046**](#errors-in-interface-declaration): *One of the parameters of an equality or inequality operator declared in an interface must be a type parameter constrained to the interface* These errors occur in three places in your code: @@ -54,7 +60,7 @@ These errors occur in three places in your code: ## Errors in interface declaration -The following errors might occur when you declare an interface with `static abstract` or `static virtual` members: +You might encounter the following errors when you declare an interface with `static abstract` or `static virtual` members: - **CS8921**: *The parameter of a unary operator must be the containing type, or its type parameter constrained to it.* - **CS8922**: *The parameter type for `++` or `--` operator must be the containing type, or its type parameter constrained to it.* @@ -62,28 +68,50 @@ The following errors might occur when you declare an interface with `static abst - **CS8924**: *One of the parameters of a binary operator must be the containing type, or its type parameter constrained to it.* - **CS8925**: *The first operand of an overloaded shift operator must have the same type as the containing type or its type parameter constrained to it* - **CS8931**: *User-defined conversion in an interface must convert to or from a type parameter on the enclosing type constrained to the enclosing type* +- **CS9046**: *One of the parameters of an equality or inequality operator declared in interface must be a type parameter constrained to the interface* -All these rules are extensions of the rules for declaring overloaded operators. The distinction is that the parameter can be either the interface type, or the interface's type parameter if that type parameter is constrained to implement the interface for its type. For binary operators, only one parameter must satisfy this rule. +For unary operators declared in an interface, ensure the parameter is either the interface type itself or a type parameter `T` where `T` is constrained to implement the interface (**CS8921**). This constraint ensures the operator can only be applied to types that implement the interface, enabling the compiler to resolve the correct implementation at compile time. -For example, `INumber` can declare an `T operator++(T)` because `T` is constrained to implement `INumber`. +For increment (`++`) and decrement (`--`) operators, verify that the parameter follows the same rules as other unary operators (**CS8922**). Additionally, the return type must either match the parameter type, derive from it, or be the interface's type parameter constrained to the interface (**CS8923**). These rules ensure that increment and decrement operations return a compatible type that can be assigned back to the original variable. -To fix these errors, ensure that the parameters of any operators defined in the interface obey these rules. You can learn more in the language reference article on [static abstract members in interfaces](../keywords/interface.md#static-abstract-and-virtual-members) or in the tutorial to [explore static abstract interface members](../../advanced-topics/interface-implementation/static-virtual-interface-members.md). +For binary operators, at least one of the two parameters must be the containing interface type or a type parameter constrained to implement the interface (**CS8924**). This requirement allows the other parameter to be any type, enabling operators like `T operator +(T left, int right)` in generic math scenarios. + +For shift operators (`<<` and `>>`), the first operand must be the containing type or its constrained type parameter (**CS8925**). The second operand follows standard shift operator rules and is typically `int`. + +For user-defined conversion operators, the conversion must involve a type parameter that is constrained to the enclosing interface type (**CS8931**). You can't define conversions between arbitrary types in an interface; the conversion must relate to types that implement the interface. + +For equality (`==`) and inequality (`!=`) operators, at least one parameter must be a type parameter constrained to the interface, not just the interface type itself (**CS9046**). This stricter requirement for equality operators ensures proper type safety when comparing instances through the interface. + +For more information about the rules for operator declarations in interfaces, see [static abstract members in interfaces](../keywords/interface.md#static-abstract-and-virtual-members). For a practical guide to implementing these patterns, see [Explore static abstract interface members](../../advanced-topics/interface-implementation/static-virtual-interface-members.md). ## Errors in type implementing interface declaration -The following errors might occur when you define a type that implements an interface with `static abstract` or `static virtual` methods: +You might encounter the following errors when you define a type that implements an interface with `static abstract` or `static virtual` methods: - **CS8928**: *Type does not implement static interface member. The method cannot implement the interface member because it is not static.* - **CS8930**: *Explicit implementation of a user-defined operator must be declared static* - **CS8932**: *'UnmanagedCallersOnly' method cannot implement interface member in type* +- **CS9044**: *Type does not implement interface member. Method cannot implicitly implement an inaccessible member.* + +When you implement a static abstract or static virtual interface member, declare the implementing method by using the `static` modifier (**CS8928**). Unlike instance interface members that are implemented by instance methods, static abstract members require static implementations because the runtime invokes them on the type itself, not on an instance. -These errors all indicate that you declared the method that implements a static abstract interface member incorrectly. These members must be declared `static`; they can't be instance members. Methods that implement interface members can't have the attribute applied to them. +For explicit implementations of user-defined operators from an interface, include the `static` modifier in the implementation (**CS8930**). Explicit interface implementations of operators follow the same static requirement as implicit implementations. + +Remove the attribute from any method that implements an interface member (**CS8932**). Methods marked by using this attribute can only be called from unmanaged code and can't participate in interface implementation because the runtime needs to call them through the interface dispatch mechanism. + +If the implementing method has more restrictive accessibility than the interface member (for example, a `private` or `internal` method implementing a `public` interface member), use explicit interface implementation syntax instead of implicit implementation (**CS9044**). Implicit implementation requires the implementing member to be at least as accessible as the interface member it implements. + +For more information about implementing interface members, see [Interfaces](../../fundamentals/types/interfaces.md) and [explicit interface implementation](../../programming-guide/interfaces/explicit-interface-implementation.md). ## Errors calling static abstract interface members -The following errors might occur when you attempt to call a member defined as a `static abstract` or `static virtual` member of an interface: +You might see the following errors when you try to call a member defined as a `static abstract` or `static virtual` member of an interface: - **CS8920**: *The interface cannot be used as type argument. Static member does not have a most specific implementation in the interface.* - **CS8926**: *A static virtual or abstract interface member can be accessed only on a type parameter.* -Calls to interface members declared as `static abstract` or `static virtual` must be resolved to at compile-time. They must resolve to a static member defined in a type that implements that interface. That means you must access those members using either a concrete type that implements the interface, or a type parameter that is constrained to implement the interface. To fix these errors, change the type used to access the static member. +When you use an interface with static abstract members as a type argument, make sure that all static abstract members have a most specific implementation available (**CS8920**). You see this error when the compiler can't determine which implementation to use, typically because multiple interface hierarchies provide conflicting default implementations or no implementation exists. + +Access static abstract or static virtual interface members through a type parameter that is constrained to implement the interface, rather than through the interface type directly (**CS8926**). For example, use `T.MemberName` where `T` is constrained by `where T : IMyInterface`, rather than `IMyInterface.MemberName`. The compiler needs a concrete type to resolve which implementation to call, and a constrained type parameter provides that concrete type at compile time through generic specialization. + +For more information about accessing static abstract members, see [static abstract members in interfaces](../keywords/interface.md#static-abstract-and-virtual-members). diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index 889c9c3486c97..c62c7a2ae55cf 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -509,8 +509,8 @@ items: operator, overloaded operator, user defined operator, CS0056, CS0057, CS0215, CS0216, CS0217, CS0218, CS0448, CS0552, CS0553, CS0554, CS0555, CS0556, CS0557, CS0558, CS0559, CS0562, CS0563, CS0564, CS0567, CS0590, - CS0660, CS0661, CS0715, CS1037, CS1553, CS1554, CS8930, CS8931, CS9023, CS9024, - CS9025, CS9027, CS9308, CS9310, CS9311, CS9312, CS9313, CS9340, CS9341, CS9342 + CS0660, CS0661, CS0715, CS1037, CS1553, CS1554, CS9023, CS9024, CS9025, CS9027, + CS9308, CS9310, CS9311, CS9312, CS9313, CS9340, CS9341, CS9342 - name: Parameter / argument mismatch href: ./compiler-messages/parameter-argument-mismatch.md displayName: > @@ -616,7 +616,7 @@ items: CS0820, CS0826, CS0846, CS1062, CS1063, CS1064, CS1552, CS1586, CS1920, CS1921, CS1925, CS1950, CS1954, CS3007, CS3016, CS9174, CS9176, CS9185, CS9186, CS9187, CS9188, CS9203, CS9208, CS9209, CS9210, CS9212, CS9213, CS9214, CS9215, CS9222, - CS9332 + CS9332, CS9354, CS9355, CS9356, CS9357, CS9358, CS9359 - name: Inline arrays href: ./compiler-messages/inline-array-errors.md displayName: > @@ -666,7 +666,7 @@ items: href: ./compiler-messages/static-abstract-interfaces.md displayName: > CS8920, CS8921, CS8922, CS8923, CS8924, CS8925, CS8926, CS8928, CS8930, CS8931, - CS8932 + CS8932, CS9044, CS9046 - name: Thread synchronization href: ./compiler-messages/lock-semantics.md displayName: CS0185, CS9216, CS9217 diff --git a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md index 1a479d527fdbf..4f00471374be6 100644 --- a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md +++ b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md @@ -1,7 +1,7 @@ --- title: "Sorry, we don't have specifics on this error" description: "List of possible resources for compiler errors and warnings that haven't been documented yet." -ms.date: 05/23/2025 +ms.date: 02/04/2026 f1_keywords: - "CS0190" - "CS0257" @@ -48,6 +48,7 @@ f1_keywords: - "CS2045" - "CS2046" - "CS3028" + # C# 5 diagnostics - "CS4001" - "CS4003" - "CS4005" @@ -75,6 +76,7 @@ f1_keywords: - "CS4031" - "CS4034" - "CS4036" + # C# 6 diagnostics - "CS7006" - "CS7012" - "CS7013" @@ -203,6 +205,7 @@ f1_keywords: - "CS8111" - "CS8112" - "CS8113" + # C# 7.0 diagnostics - "CS8115" - "CS8116" - "CS8117" @@ -231,6 +234,7 @@ f1_keywords: - "CS8190" - "CS8191" - "CS8197" + # C# 7.0 diagnostics - "CS8199" - "CS8202" - "CS8204" @@ -238,6 +242,7 @@ f1_keywords: - "CS8206" - "CS8208" - "CS8209" + # C# 7.1 diagnostics - "CS8300" - "CS8301" - "CS8305" @@ -246,6 +251,7 @@ f1_keywords: - "CS8309" - "CS8310" - "CS8312" + # C# 7.2 diagnostics - "CS8321" - "CS8323" - "CS8328" @@ -278,6 +284,7 @@ f1_keywords: - "CS8386" - "CS8387" - "CS8389" + # C# 7.3 diagnostics - "CS8412" - "CS8413" - "CS8414" @@ -327,6 +334,7 @@ f1_keywords: - "CS8715" - "CS8716" - "CS8750" + # C# 9 diagnostics start here - "CS8751" - "CS8752" - "CS8753" @@ -438,12 +446,6 @@ f1_keywords: - "CS8973" - "CS8974" - "CS8976" - # C# 11 errors start here - - "CS8984" - - "CS8989" - - "CS9044" - - "CS9046" - - "CS9064" # Coming in C# 15 - "CS9343" - "CS9344" @@ -456,12 +458,6 @@ f1_keywords: - "CS9351" - "CS9352" - "CS9353" - - "CS9354" - - "CS9355" - - "CS9356" - - "CS9357" - - "CS9358" - - "CS9359" helpviewer_keywords: - "errors [C#], additional information" --- diff --git a/docs/csharp/specification/feature-spec-overview.md b/docs/csharp/specification/feature-spec-overview.md index 07a79d999dd6c..e774bec7d7372 100644 --- a/docs/csharp/specification/feature-spec-overview.md +++ b/docs/csharp/specification/feature-spec-overview.md @@ -1,15 +1,15 @@ --- title: "Feature specifications" description: "Understand the relationships among the ECMA C# standard and the feature specifications for newer language features implemented in roslyn." -ms.date: 05/08/2024 +ms.date: 02/06/2026 --- # Feature specifications -Because the [C# standard specification](overview.md) has fallen behind the latest C# implementation, this section contains the [Microsoft specifications](~/_csharplang/proposals/csharp-10.0/enhanced-line-directives.md) for those newer features that haven't yet been incorporated into the standard. You can read these specifications to get information on newer features. +Because the [C# standard specification](overview.md) fell behind the latest C# implementation, this section contains the [Microsoft specifications](~/_csharplang/proposals/csharp-10.0/enhanced-line-directives.md) for those newer features that aren't yet incorporated into the standard. You can read these specifications to get information on newer features. -The feature specifications began as proposals for the design. They include proposed changes to the standard. The C# language design team and compiler team produce these feature specifications. The purpose of the proposals is to guide the design and implementation of the feature. They might include proposed features that haven't yet been implemented. The actual implementation might have modified behavior. Those changes are captured in the language design meeting (LDM) notes. The LDM notes are the minutes of the language design meetings. In most cases, the pertinent LDM notes are linked from the feature specifications. +The feature specifications began as proposals for the design. They include proposed changes to the standard. The C# language design team and compiler team produce these feature specifications. The purpose of the proposals is to guide the design and implementation of the feature. They might include proposed features that aren't yet implemented. The actual implementation might have modified behavior. The language design meeting (LDM) notes capture those changes. The LDM notes are the minutes of the language design meetings. In most cases, the pertinent LDM notes are linked from the feature specifications. -As the committee works on newer versions, the feature specifications are removed from this site, and those links are redirected to the updated sections of the standard. In the meantime, the feature specifications represent the best information on those features. +As the committee works on newer versions, the standard replaces the feature specifications. In the meantime, the feature specifications represent the best information on those features. ## See also diff --git a/docs/csharp/specification/overview.md b/docs/csharp/specification/overview.md index bb9e72f3204f3..d743d3d1dec46 100644 --- a/docs/csharp/specification/overview.md +++ b/docs/csharp/specification/overview.md @@ -1,16 +1,18 @@ --- title: "Standard specification" description: "Understand the relationships among the ECMA C# standard and the working draft." -ms.date: 05/08/2024 +ms.date: 02/05/2026 --- # C# standard specification -The [C# language specification](~/_csharpstandard/standard/README.md) is the definitive source for the C# language. The [ECMA C# standard committee (TC49-TG2)](https://www.ecma-international.org/task-groups/tc49-tg2/) produces the specification. The committee is currently working on version 8 of the standard. The draft published here includes some, but not all, of the C# 8 features. The committee uses [Microsoft specifications](https://github.com/dotnet/csharplang/tree/main/proposals) and [language design meeting (LDM) notes](https://github.com/dotnet/csharplang/tree/main/meetings) to produce the specification. +The [C# language specification](~/_csharpstandard/standard/README.md) is the definitive source for the C# language. The [ECMA C# standard committee (TC49-TG2)](https://www.ecma-international.org/task-groups/tc49-tg2/) produces the specification. The standard document versions align with the C# language versions. The C# 8 standard corresponds to C# 8.0. + +The committee is currently working on version 8 of the standard. The draft published here is a feature complete draft of C# 8. The committee uses [Microsoft specifications](https://github.com/dotnet/csharplang/tree/main/proposals) and [language design meeting (LDM) notes](https://github.com/dotnet/csharplang/tree/main/meetings) to produce the specification. This section contains the latest working draft of the [C# language specification](~/_csharpstandard/standard/README.md). The latest working draft is published here before being submitted to ECMA for approval. The committee works in the [dotnet/csharpstandard](https://github.com/dotnet/csharpstandard) repository. You can track the committee's progress and participate in the standard work there. > [!NOTE] -> The committee works to update the C# language specification, but it has fallen behind the current implementation. For specifications about current features, see [Feature specifications](feature-spec-overview.md). +> The committee works to update the C# language specification, but it fell behind the current implementation. For specifications about current features, see [Feature specifications](feature-spec-overview.md). ## See also diff --git a/docs/framework/configure-apps/file-schema/runtime/generatepublisherevidence-element.md b/docs/framework/configure-apps/file-schema/runtime/generatepublisherevidence-element.md index c40a93307e858..9ccbc3302fa3d 100644 --- a/docs/framework/configure-apps/file-schema/runtime/generatepublisherevidence-element.md +++ b/docs/framework/configure-apps/file-schema/runtime/generatepublisherevidence-element.md @@ -54,10 +54,7 @@ Specifies whether the runtime creates ev ## Remarks -> [!NOTE] -> In the .NET Framework 4 and later, this element has no effect on assembly load times. - - The common language runtime (CLR) tries to verify the Authenticode signature at load time to create evidence for the assembly. However, by default, most applications do not need evidence. Standard CAS policy does not rely on the . You should avoid the unnecessary startup cost associated with verifying the publisher signature unless your application executes on a computer with custom CAS policy, or is intending to satisfy demands for in a partial-trust environment. (Demands for identity permissions always succeed in a full-trust environment.) +The common language runtime (CLR) tries to verify the Authenticode signature at load time to create evidence for the assembly. However, by default, most applications do not need evidence. Standard CAS policy does not rely on the . You should avoid the unnecessary startup cost associated with verifying the publisher signature unless your application executes on a computer with custom CAS policy, or is intending to satisfy demands for in a partial-trust environment. (Demands for identity permissions always succeed in a full-trust environment.) > [!NOTE] > We recommend that services use the `` element to improve startup performance. Using this element can also help avoid delays that can cause a time-out and the cancellation of the service startup. diff --git a/docs/standard/events/how-to-raise-and-consume-events.md b/docs/standard/events/how-to-raise-and-consume-events.md index 940e71fdfe780..d941ad84806ae 100644 --- a/docs/standard/events/how-to-raise-and-consume-events.md +++ b/docs/standard/events/how-to-raise-and-consume-events.md @@ -2,7 +2,6 @@ title: "How to: Raise and Consume Events" description: Raise & consume events in .NET. See examples that use the EventHandler delegate, the EventHandler delegate, & a custom delegate. ms.date: 10/20/2025 -ms.custom: devdivchpfy22 dev_langs: - "csharp" - "vb" @@ -11,31 +10,32 @@ helpviewer_keywords: - "raising events" - "events [.NET], samples" --- -# How to: Raise and Consume Events +# How to: Raise and consume events -The examples in this article show how to work with events. They include examples of the delegate, the delegate, and a custom delegate to illustrate events with and without data. +The examples in this article show how to work with events. They include examples of the delegate, the delegate, and a custom delegate to illustrate events with and without data. The examples use concepts described in the [Events](index.md) article. ## Example 1 - The first example shows how to raise and consume an event that doesn't have data. It contains a class named `Counter` that has an event called `ThresholdReached`. This event is raised when a counter value equals or exceeds a threshold value. The delegate is associated with the event because no event data is provided. +This first example shows how to raise and consume an event that doesn't have data. It contains a class named `Counter` that has an event called `ThresholdReached`. This event is raised when a counter value equals or exceeds a threshold value. The delegate is associated with the event because no event data is provided. - [!code-csharp[EventsOverview#5](../../../samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programnodata.cs#5)] - [!code-vb[EventsOverview#5](../../../samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1nodata.vb#5)] +[!code-csharp[EventsOverview#5](./snippets/raise-consume/csharp/programnodata.cs#5)] +[!code-vb[EventsOverview#5](./snippets/raise-consume/vb/module1nodata.vb#5)] ## Example 2 - The second example shows how to raise and consume an event that provides data. The delegate is associated with the event, and an instance of a custom event data object is provided. - [!code-csharp[EventsOverview#6](../../../samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdata.cs#6)] - [!code-vb[EventsOverview#6](../../../samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdata.vb#6)] +This second example shows how to raise and consume an event that provides data. The delegate is associated with the event, and an instance of a custom event data object is provided. + +[!code-csharp[EventsOverview#6](./snippets/raise-consume/csharp/programwithdata.cs#6)] +[!code-vb[EventsOverview#6](./snippets/raise-consume/vb/module1withdata.vb#6)] ## Example 3 - The third example shows how to declare a delegate for an event. The delegate is named `ThresholdReachedEventHandler`. This example is just an illustration. Typically, you don't have to declare a delegate for an event because you can use either the or the delegate. You should declare a delegate only in rare scenarios, such as making your class available to legacy code that can't use generics. +This third example shows how to declare a delegate for an event. The delegate is named `ThresholdReachedEventHandler`. This example is just an illustration. Typically, you don't have to declare a delegate for an event because you can use either the or the delegate. You should declare a delegate only in rare scenarios, such as making your class available to legacy code that can't use generics. - [!code-csharp[EventsOverview#7](../../../samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdelegate.cs#7)] - [!code-vb[EventsOverview#7](../../../samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdelegate.vb#7)] +[!code-csharp[EventsOverview#7](./snippets/raise-consume/csharp/programwithdelegate.cs#7)] +[!code-vb[EventsOverview#7](./snippets/raise-consume/vb/module1withdelegate.vb#7)] ## See also diff --git a/docs/standard/events/index.md b/docs/standard/events/index.md index dd763be6dc2b5..c6b27461b3618 100644 --- a/docs/standard/events/index.md +++ b/docs/standard/events/index.md @@ -15,8 +15,6 @@ helpviewer_keywords: - "events [.NET]" - "events [.NET Core]" - "events [.NET]" -ms.assetid: b6f65241-e0ad-4590-a99f-200ce741bb1f -#customer intent: As a .NET developer, I want to raise and handle .NET events based on the delegate model, so I can enable subscribers to register with or receive notifications from providers. --- # Handle and raise events @@ -33,8 +31,8 @@ Typically, to raise an event, you add a method that is marked as `protected` and The following example shows how to declare an event named `ThresholdReached`. The event is associated with the delegate and raised in a method named `OnThresholdReached`: -[!code-csharp[EventsOverview#1](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#1)] -[!code-vb[EventsOverview#1](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#1)] +[!code-csharp[EventsOverview#1](./snippets/raise-consume/csharp/programtruncated.cs#1)] +[!code-vb[EventsOverview#1](./snippets/raise-consume/vb/module1truncated.vb#1)] ## Declare delegate signatures for event handlers @@ -48,8 +46,8 @@ Delegates are [multicast](xref:System.MulticastDelegate) class objects, which me Use the and delegate types to define the needed delegate. You mark a delegate with the `delegate` type in [C#](../../csharp/language-reference/builtin-types/reference-types.md#the-delegate-type) or the `Delegate` type in [Visual Basic](../../visual-basic/language-reference/statements/delegate-statement.md) in the declaration. The following example shows how to declare a delegate named `ThresholdReachedEventHandler`: -[!code-csharp[EventsOverview#4](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#4)] -[!code-vb[EventsOverview#4](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#4)] +[!code-csharp[EventsOverview#4](./snippets/raise-consume/csharp/programtruncated.cs#4)] +[!code-vb[EventsOverview#4](./snippets/raise-consume/vb/module1truncated.vb#4)] ## Work with event data classes @@ -61,8 +59,8 @@ You can create a class that derives from the class to pr The following example shows an event data class named `ThresholdReachedEventArgs` that contains properties that are specific to the event being raised: -[!code-csharp[EventsOverview#3](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#3)] -[!code-vb[EventsOverview#3](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#3)] +[!code-csharp[EventsOverview#3](./snippets/raise-consume/csharp/programtruncated.cs#3)] +[!code-vb[EventsOverview#3](./snippets/raise-consume/vb/module1truncated.vb#3)] ## Respond to events with handlers @@ -70,8 +68,8 @@ To respond to an event, you define an event handler method in the event receiver The following example shows an event handler method named `c_ThresholdReached` that matches the signature for the delegate. The method subscribes to the `ThresholdReached` event: -[!code-csharp[EventsOverview#2](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#2)] -[!code-vb[EventsOverview#2](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#2)] +[!code-csharp[EventsOverview#2](./snippets/raise-consume/csharp/programtruncated.cs#2)] +[!code-vb[EventsOverview#2](./snippets/raise-consume/vb/module1truncated.vb#2)] ## Use static and dynamic event handlers diff --git a/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/DesignTimeBuild/.dtbcache.v2 b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000000000..f3437f8c87d83 Binary files /dev/null and b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/DesignTimeBuild/.dtbcache.v2 differ diff --git a/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/FileContentIndex/110eb034-4cd0-41ab-b975-3f6c4c4beb0d.vsidx b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/FileContentIndex/110eb034-4cd0-41ab-b975-3f6c4c4beb0d.vsidx new file mode 100644 index 0000000000000..ac19447a4035b Binary files /dev/null and b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/FileContentIndex/110eb034-4cd0-41ab-b975-3f6c4c4beb0d.vsidx differ diff --git a/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/v18/.futdcache.v2 b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/v18/.futdcache.v2 new file mode 100644 index 0000000000000..9fe88a5a33218 Binary files /dev/null and b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/v18/.futdcache.v2 differ diff --git a/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/v18/.suo b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/v18/.suo new file mode 100644 index 0000000000000..4ccad37b405f5 Binary files /dev/null and b/docs/standard/events/snippets/raise-consume/csharp/eventsoverview/v18/.suo differ diff --git a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programnodata.cs b/docs/standard/events/snippets/raise-consume/csharp/programnodata.cs similarity index 53% rename from samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programnodata.cs rename to docs/standard/events/snippets/raise-consume/csharp/programnodata.cs index ea92dd0b743c6..4cb743088d32c 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programnodata.cs +++ b/docs/standard/events/snippets/raise-consume/csharp/programnodata.cs @@ -1,13 +1,11 @@ -// -using System; - -namespace ConsoleApplication1 +namespace ConsoleApplication1 { + // class ProgramOne { - static void Main(string[] args) + static void Main() { - Counter c = new Counter(new Random().Next(10)); + Counter c = new(new Random().Next(10)); c.ThresholdReached += c_ThresholdReached; Console.WriteLine("press 'a' key to increase total"); @@ -18,33 +16,28 @@ static void Main(string[] args) } } - static void c_ThresholdReached(object sender, EventArgs e) + static void c_ThresholdReached(object? sender, EventArgs e) { Console.WriteLine("The threshold was reached."); Environment.Exit(0); } } - class Counter + class Counter(int passedThreshold) { - private int threshold; - private int total; - - public Counter(int passedThreshold) - { - threshold = passedThreshold; - } + private readonly int _threshold = passedThreshold; + private int _total; public void Add(int x) { - total += x; - if (total >= threshold) + _total += x; + if (_total >= _threshold) { ThresholdReached?.Invoke(this, EventArgs.Empty); } } - public event EventHandler ThresholdReached; + public event EventHandler? ThresholdReached; } + // } -// diff --git a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs b/docs/standard/events/snippets/raise-consume/csharp/programtruncated.cs similarity index 64% rename from samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs rename to docs/standard/events/snippets/raise-consume/csharp/programtruncated.cs index 3507c52fb8a80..4a961ffd27d47 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs +++ b/docs/standard/events/snippets/raise-consume/csharp/programtruncated.cs @@ -1,6 +1,4 @@ -using System; - -namespace ConsoleApplication2 +namespace ConsoleApplication2 { // class ProgramTwo @@ -10,10 +8,10 @@ static void Main() var c = new Counter(); c.ThresholdReached += c_ThresholdReached; - // provide remaining implementation for the class + // Provide remaining implementation for the class... } - static void c_ThresholdReached(object sender, EventArgs e) + static void c_ThresholdReached(object? sender, EventArgs e) { Console.WriteLine("The threshold was reached."); } @@ -23,14 +21,14 @@ static void c_ThresholdReached(object sender, EventArgs e) // class Counter { - public event EventHandler ThresholdReached; + public event EventHandler? ThresholdReached; protected virtual void OnThresholdReached(EventArgs e) { ThresholdReached?.Invoke(this, e); } - // provide remaining implementation for the class + // Provide remaining implementation for the class... } // @@ -43,6 +41,8 @@ public class ThresholdReachedEventArgs : EventArgs // // - public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e); + public delegate void ThresholdReachedEventHandler( + object sender, + ThresholdReachedEventArgs e); // } diff --git a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdata.cs b/docs/standard/events/snippets/raise-consume/csharp/programwithdata.cs similarity index 57% rename from samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdata.cs rename to docs/standard/events/snippets/raise-consume/csharp/programwithdata.cs index ce6f3957d1f63..4e0dfcf66c789 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdata.cs +++ b/docs/standard/events/snippets/raise-consume/csharp/programwithdata.cs @@ -1,13 +1,11 @@ -// -using System; - -namespace ConsoleApplication3 +namespace ConsoleApplication3 { + // class ProgramThree { - static void Main(string[] args) + static void Main() { - Counter c = new Counter(new Random().Next(10)); + Counter c = new(new Random().Next(10)); c.ThresholdReached += c_ThresholdReached; Console.WriteLine("press 'a' key to increase total"); @@ -18,30 +16,25 @@ static void Main(string[] args) } } - static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e) + static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e) { Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}."); Environment.Exit(0); } } - class Counter + class Counter(int passedThreshold) { - private int threshold; - private int total; - - public Counter(int passedThreshold) - { - threshold = passedThreshold; - } + private readonly int _threshold = passedThreshold; + private int _total; public void Add(int x) { - total += x; - if (total >= threshold) + _total += x; + if (_total >= _threshold) { ThresholdReachedEventArgs args = new ThresholdReachedEventArgs(); - args.Threshold = threshold; + args.Threshold = _threshold; args.TimeReached = DateTime.Now; OnThresholdReached(args); } @@ -49,14 +42,10 @@ public void Add(int x) protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { - EventHandler handler = ThresholdReached; - if (handler != null) - { - handler(this, e); - } + ThresholdReached?.Invoke(this, e); } - public event EventHandler ThresholdReached; + public event EventHandler? ThresholdReached; } public class ThresholdReachedEventArgs : EventArgs @@ -64,5 +53,5 @@ public class ThresholdReachedEventArgs : EventArgs public int Threshold { get; set; } public DateTime TimeReached { get; set; } } + // } -// diff --git a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdelegate.cs b/docs/standard/events/snippets/raise-consume/csharp/programwithdelegate.cs similarity index 61% rename from samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdelegate.cs rename to docs/standard/events/snippets/raise-consume/csharp/programwithdelegate.cs index a9294a3f7aff1..c83c2038b38d4 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdelegate.cs +++ b/docs/standard/events/snippets/raise-consume/csharp/programwithdelegate.cs @@ -1,13 +1,11 @@ -// -using System; - -namespace ConsoleApplication4 +namespace ConsoleApplication4 { + // class ProgramFour { - static void Main(string[] args) + static void Main() { - Counter c = new Counter(new Random().Next(10)); + Counter c = new(new Random().Next(10)); c.ThresholdReached += c_ThresholdReached; Console.WriteLine("press 'a' key to increase total"); @@ -27,21 +25,21 @@ static void c_ThresholdReached(Object sender, ThresholdReachedEventArgs e) class Counter { - private int threshold; - private int total; + private readonly int _threshold; + private int _total; public Counter(int passedThreshold) { - threshold = passedThreshold; + _threshold = passedThreshold; } public void Add(int x) { - total += x; - if (total >= threshold) + _total += x; + if (_total >= _threshold) { - ThresholdReachedEventArgs args = new ThresholdReachedEventArgs(); - args.Threshold = threshold; + ThresholdReachedEventArgs args = new(); + args.Threshold = _threshold; args.TimeReached = DateTime.Now; OnThresholdReached(args); } @@ -49,11 +47,7 @@ public void Add(int x) protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { - ThresholdReachedEventHandler handler = ThresholdReached; - if (handler != null) - { - handler(this, e); - } + ThresholdReached?.Invoke(this, e); } public event ThresholdReachedEventHandler ThresholdReached; @@ -65,6 +59,8 @@ public class ThresholdReachedEventArgs : EventArgs public DateTime TimeReached { get; set; } } - public delegate void ThresholdReachedEventHandler(Object sender, ThresholdReachedEventArgs e); + public delegate void ThresholdReachedEventHandler( + object sender, + ThresholdReachedEventArgs e); + // } -// diff --git a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/eventsoverview.csproj b/docs/standard/events/snippets/raise-consume/csharp/project.csproj similarity index 84% rename from samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/eventsoverview.csproj rename to docs/standard/events/snippets/raise-consume/csharp/project.csproj index 6d0d592a5ff2f..a5314e08a612e 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/eventsoverview.csproj +++ b/docs/standard/events/snippets/raise-consume/csharp/project.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable true Exe diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1nodata.vb b/docs/standard/events/snippets/raise-consume/vb/module1nodata.vb similarity index 69% rename from samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1nodata.vb rename to docs/standard/events/snippets/raise-consume/vb/module1nodata.vb index 1fb6789349f4c..b99edef2ca809 100644 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1nodata.vb +++ b/docs/standard/events/snippets/raise-consume/vb/module1nodata.vb @@ -1,8 +1,8 @@ -' +' Module Module1 Sub Main() - Dim c As Counter = New Counter(New Random().Next(10)) + Dim c As New Counter(New Random().Next(10)) AddHandler c.ThresholdReached, AddressOf c_ThresholdReached Console.WriteLine("press 'a' key to increase total") @@ -19,17 +19,17 @@ Module Module1 End Module Class Counter - Private threshold As Integer - Private total As Integer + Private ReadOnly _threshold As Integer + Private _total As Integer Public Sub New(passedThreshold As Integer) - threshold = passedThreshold + _threshold = passedThreshold End Sub Public Sub Add(x As Integer) - total = total + x - If (total >= threshold) Then - ThresholdReached?.Invoke(this. EventArgs.Empty) + _total += x + If (_total >= _threshold) Then + RaiseEvent ThresholdReached(Me, EventArgs.Empty) End If End Sub diff --git a/docs/standard/events/snippets/raise-consume/vb/module1truncated.vb b/docs/standard/events/snippets/raise-consume/vb/module1truncated.vb new file mode 100644 index 0000000000000..d4111b9173091 --- /dev/null +++ b/docs/standard/events/snippets/raise-consume/vb/module1truncated.vb @@ -0,0 +1,42 @@ +Namespace Module2Example + ' + Module Module2 + + Sub Main() + Dim c As New Counter() + AddHandler c.ThresholdReached, AddressOf c_ThresholdReached + + ' provide remaining implementation for the class + End Sub + + Sub c_ThresholdReached(sender As Object, e As EventArgs) + Console.WriteLine("The threshold was reached.") + End Sub + End Module + ' + + ' + Public Class Counter + Public Event ThresholdReached As EventHandler + + Protected Overridable Sub OnThresholdReached(e As EventArgs) + RaiseEvent ThresholdReached(Me, e) + End Sub + + ' provide remaining implementation for the class + End Class + ' + + ' + Public Class ThresholdReachedEventArgs + Inherits EventArgs + + Public Property Threshold As Integer + Public Property TimeReached As Date + End Class + ' + + ' + Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs) + ' +End Namespace diff --git a/docs/standard/events/snippets/raise-consume/vb/module1withdata.vb b/docs/standard/events/snippets/raise-consume/vb/module1withdata.vb new file mode 100644 index 0000000000000..126b367ddc8fe --- /dev/null +++ b/docs/standard/events/snippets/raise-consume/vb/module1withdata.vb @@ -0,0 +1,56 @@ +Namespace Module3Example + ' + Module Module3 + + Sub Main() + Dim c As New Counter(New Random().Next(10)) + AddHandler c.ThresholdReached, AddressOf c_ThresholdReached + + Console.WriteLine("press 'a' key to increase total") + While Console.ReadKey(True).KeyChar = "a" + Console.WriteLine("adding one") + c.Add(1) + End While + End Sub + + Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) + Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) + Environment.Exit(0) + End Sub + End Module + + Class Counter + Private ReadOnly _threshold As Integer + Private _total As Integer + + Public Sub New(passedThreshold As Integer) + _threshold = passedThreshold + End Sub + + Public Sub Add(x As Integer) + _total += x + If (_total >= _threshold) Then + Dim args As New ThresholdReachedEventArgs With { + .Threshold = _threshold, + .TimeReached = Date.Now + } + OnThresholdReached(args) + End If + End Sub + + Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) + RaiseEvent ThresholdReached(Me, e) + End Sub + + Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs) + End Class + + Class ThresholdReachedEventArgs + Inherits EventArgs + + Public Property Threshold As Integer + Public Property TimeReached As Date + End Class + ' +End Namespace + diff --git a/docs/standard/events/snippets/raise-consume/vb/module1withdelegate.vb b/docs/standard/events/snippets/raise-consume/vb/module1withdelegate.vb new file mode 100644 index 0000000000000..440ec3376144b --- /dev/null +++ b/docs/standard/events/snippets/raise-consume/vb/module1withdelegate.vb @@ -0,0 +1,59 @@ + +Namespace Module4Example + ' + Module Module4 + + Sub Main() + Dim c As New Counter(New Random().Next(10)) + AddHandler c.ThresholdReached, AddressOf c_ThresholdReached + + Console.WriteLine("press 'a' key to increase total") + While Console.ReadKey(True).KeyChar = "a" + Console.WriteLine("adding one") + c.Add(1) + End While + End Sub + + Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) + Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) + Environment.Exit(0) + End Sub + End Module + + Class Counter + Private ReadOnly _threshold As Integer + Private _total As Integer + + Public Sub New(passedThreshold As Integer) + _threshold = passedThreshold + End Sub + + Public Sub Add(x As Integer) + _total += x + If (_total >= _threshold) Then + Dim args As New ThresholdReachedEventArgs With { + .Threshold = _threshold, + .TimeReached = Date.Now + } + OnThresholdReached(args) + End If + End Sub + + Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) + RaiseEvent ThresholdReached(Me, e) + End Sub + + Public Event ThresholdReached As ThresholdReachedEventHandler + End Class + + Public Class ThresholdReachedEventArgs + Inherits EventArgs + + Public Property Threshold As Integer + Public Property TimeReached As Date + End Class + + Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs) + ' + +End Namespace diff --git a/docs/standard/events/snippets/raise-consume/vb/project.vbproj b/docs/standard/events/snippets/raise-consume/vb/project.vbproj new file mode 100644 index 0000000000000..97b1d2a0dc4e7 --- /dev/null +++ b/docs/standard/events/snippets/raise-consume/vb/project.vbproj @@ -0,0 +1,10 @@ + + + + net10.0 + enable + true + Library + + + diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb b/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb deleted file mode 100644 index 0b78397d82f75..0000000000000 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb +++ /dev/null @@ -1,40 +0,0 @@ -' -Module Module1 - - Sub Main() - Dim c As New Counter() - AddHandler c.ThresholdReached, AddressOf c_ThresholdReached - - ' provide remaining implementation for the class - End Sub - - Sub c_ThresholdReached(sender As Object, e As EventArgs) - Console.WriteLine("The threshold was reached.") - End Sub -End Module -' - -' -Public Class Counter - Public Event ThresholdReached As EventHandler - - Protected Overridable Sub OnThresholdReached(e As EventArgs) - RaiseEvent ThresholdReached(Me, e) - End Sub - - ' provide remaining implementation for the class -End Class -' - -' -Public Class ThresholdReachedEventArgs - Inherits EventArgs - - Public Property Threshold As Integer - Public Property TimeReached As DateTime -End Class -' - -' -Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs) -' diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdata.vb b/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdata.vb deleted file mode 100644 index b424a89627c4c..0000000000000 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdata.vb +++ /dev/null @@ -1,53 +0,0 @@ -' -Module Module1 - - Sub Main() - Dim c As Counter = New Counter(New Random().Next(10)) - AddHandler c.ThresholdReached, AddressOf c_ThresholdReached - - Console.WriteLine("press 'a' key to increase total") - While Console.ReadKey(True).KeyChar = "a" - Console.WriteLine("adding one") - c.Add(1) - End While - End Sub - - Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) - Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) - Environment.Exit(0) - End Sub -End Module - -Class Counter - Private threshold As Integer - Private total As Integer - - Public Sub New(passedThreshold As Integer) - threshold = passedThreshold - End Sub - - Public Sub Add(x As Integer) - total = total + x - If (total >= threshold) Then - Dim args As ThresholdReachedEventArgs = New ThresholdReachedEventArgs() - args.Threshold = threshold - args.TimeReached = DateTime.Now - OnThresholdReached(args) - End If - End Sub - - Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) - RaiseEvent ThresholdReached(Me, e) - End Sub - - Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs) -End Class - -Class ThresholdReachedEventArgs - Inherits EventArgs - - Public Property Threshold As Integer - Public Property TimeReached As DateTime -End Class -' - diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdelegate.vb b/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdelegate.vb deleted file mode 100644 index 0652accefaacb..0000000000000 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdelegate.vb +++ /dev/null @@ -1,55 +0,0 @@ -' -Module Module1 - - Sub Main() - Dim c As Counter = New Counter(New Random().Next(10)) - AddHandler c.ThresholdReached, AddressOf c_ThresholdReached - - Console.WriteLine("press 'a' key to increase total") - While Console.ReadKey(True).KeyChar = "a" - Console.WriteLine("adding one") - c.Add(1) - End While - End Sub - - Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs) - Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached) - Environment.Exit(0) - End Sub -End Module - -Class Counter - Private threshold As Integer - Private total As Integer - - Public Sub New(passedThreshold As Integer) - threshold = passedThreshold - End Sub - - Public Sub Add(x As Integer) - total = total + x - If (total >= threshold) Then - Dim args As ThresholdReachedEventArgs = New ThresholdReachedEventArgs() - args.Threshold = threshold - args.TimeReached = DateTime.Now - OnThresholdReached(args) - End If - End Sub - - Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs) - RaiseEvent ThresholdReached(Me, e) - End Sub - - Public Event ThresholdReached As ThresholdReachedEventHandler -End Class - -Public Class ThresholdReachedEventArgs - Inherits EventArgs - - Public Property Threshold As Integer - Public Property TimeReached As DateTime -End Class - -Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs) -' -