Skip to content

Prefer StringComparisons over StringComparers for string comparisons#15000

Closed
JamesNK wants to merge 9 commits intorelease/13.2from
prefer-stringcomparisons-over-stringcomparers
Closed

Prefer StringComparisons over StringComparers for string comparisons#15000
JamesNK wants to merge 9 commits intorelease/13.2from
prefer-stringcomparisons-over-stringcomparers

Conversation

@JamesNK
Copy link
Copy Markdown
Member

@JamesNK JamesNK commented Mar 6, 2026

Description

Prefer StringComparisons over StringComparers for direct string comparison operations (Equals, Compare).

StringComparers members return StringComparer instances which should only be used with APIs that require IEqualityComparer<string> or IComparer<string> — such as dictionary/hashset constructors, OrderBy, GroupBy, ToDictionary, Except, and collection Contains.

For direct string equality or comparison checks, string.Equals() / string.Compare() with StringComparison (via StringComparisons) is the preferred pattern because it avoids the overhead of the comparer interface dispatch and is more idiomatic.

Changes (17 files, 39 replacements)

  • StringComparer.OrdinalIgnoreCase.Equals(a, b)string.Equals(a, b, StringComparison.OrdinalIgnoreCase)
  • StringComparers.*.Equals(a, b)string.Equals(a, b, StringComparisons.*)
  • StringComparers.*.Compare(a, b)string.Compare(a, b, StringComparisons.*)

All remaining StringComparers usages are correct — they are passed to APIs that require IEqualityComparer<string> or IComparer<string>.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

Copilot AI review requested due to automatic review settings March 6, 2026 07:57
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 6, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 15000

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 15000"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates string comparison call sites across Hosting/CLI/Dashboard code to use string.Equals / string.Compare with centralized StringComparisons constants, reserving StringComparers for APIs that require IEqualityComparer<string> / IComparer<string>.

Changes:

  • Replaces direct equality checks using StringComparers.*.Equals(a, b) with string.Equals(a, b, StringComparisons.*) (or StringComparison.* where appropriate).
  • Replaces direct ordering comparisons using StringComparers.*.Compare(a, b) with string.Compare(a, b, StringComparisons.*).
  • Updates multiple resource/endpoint lookup filters to use StringComparisons-based comparisons consistently.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Shared/Model/ResourceSourceViewModel.cs Switches resource type checks to string.Equals(..., StringComparisons.ResourceType).
src/Aspire.Hosting/ResourceBuilderExtensions.cs Updates endpoint name matching to string.Equals(..., StringComparisons.EndpointAnnotationName).
src/Aspire.Hosting/Health/ResourceHealthCheckService.cs Updates health report change detection to string.Equals(..., StringComparisons.HealthReportPropertyValue).
src/Aspire.Hosting/Dcp/DcpExecutor.cs Updates resource/endpoint matching predicates to string.Equals(..., StringComparisons.*).
src/Aspire.Hosting/Dashboard/DashboardEventHandlers.cs Updates dashboard resource identification checks to string.Equals(..., StringComparisons.ResourceName).
src/Aspire.Hosting/BuiltInDistributedApplicationEventSubscriptionHandlers.cs Updates dashboard resource lookup to string.Equals(..., StringComparisons.ResourceName).
src/Aspire.Hosting/Backchannel/DashboardUrlsHelper.cs Updates dashboard resource lookup to string.Equals(..., StringComparisons.ResourceName).
src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs Updates resource existence checks and dashboard skipping logic to string.Equals(..., StringComparisons.ResourceName).
src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs Updates endpoint lookup by name to string.Equals(..., StringComparisons.EndpointAnnotationName).
src/Aspire.Hosting/ApplicationModel/EndpointReference.cs Updates scheme/name/network matching to string.Equals(..., StringComparisons.*).
src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs Updates endpoint name match to string.Equals(..., StringComparison.OrdinalIgnoreCase).
src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs Updates endpoint name lookups to string.Equals(..., StringComparisons.EndpointAnnotationName).
src/Aspire.Dashboard/Model/ResourceViewModelExtensions.cs Updates resource type checks to string.Equals(..., StringComparisons.ResourceType).
src/Aspire.Dashboard/Model/ResourceViewModel.cs Updates name comparer to string.Compare(..., StringComparisons.ResourceName).
src/Aspire.Dashboard/Components/ResourcesGridColumns/ResourceNameDisplay.razor Updates container lifetime check to string.Equals(..., StringComparison.Ordinal).
src/Aspire.Dashboard/Components/Dialogs/SettingsDialog.razor.cs Updates culture name comparison to string.Equals(..., StringComparisons.CultureName).
src/Aspire.Dashboard/Components/Dialogs/ManageDataDialog.razor.cs Updates selection removal predicate to string.Equals(..., StringComparisons.ResourceName).

@JamesNK JamesNK force-pushed the prefer-stringcomparisons-over-stringcomparers branch from 3f4b6dd to 2a1bd0a Compare March 6, 2026 10:25
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 6, 2026

🎬 CLI E2E Test Recordings

The following terminal recordings are available for commit 5e5c31b:

Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndPublishToKubernetes ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateEmptyAppHostProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RunWithMissingAwaitShowsHelpfulError ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
TypeScriptAppHostWithProjectReferenceIntegration ▶️ View Recording

📹 Recordings uploaded automatically from CI run #22982760216

@JamesNK JamesNK force-pushed the prefer-stringcomparisons-over-stringcomparers branch from 2a1bd0a to 2ac6d5a Compare March 6, 2026 11:20
@JamesNK JamesNK force-pushed the prefer-stringcomparisons-over-stringcomparers branch 2 times, most recently from b1ce73e to d6bee12 Compare March 7, 2026 10:55
JamesNK added 2 commits March 9, 2026 09:39
…perations

Replace StringComparer.*.Equals()/Compare() and StringComparers.*.Equals()/Compare()
calls with string.Equals()/string.Compare() using StringComparison/StringComparisons.
StringComparers should only be used with APIs that require IEqualityComparer<string>
or IComparer<string> (e.g., dictionary constructors, OrderBy, GroupBy, HashSet).
@JamesNK JamesNK force-pushed the prefer-stringcomparisons-over-stringcomparers branch from d6bee12 to 9013c4f Compare March 9, 2026 01:39
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change intentional?

Copy link
Copy Markdown
Member

@joperezr joperezr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the launchsettings.json comment, this looks good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants