Skip to content

Add CA2028: Avoid redundant Regex.IsMatch before Regex.Match#54074

Closed
Copilot wants to merge 2 commits intomainfrom
copilot/address-review-comments-pr54071
Closed

Add CA2028: Avoid redundant Regex.IsMatch before Regex.Match#54074
Copilot wants to merge 2 commits intomainfrom
copilot/address-review-comments-pr54071

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 26, 2026

Implements CA2028, a new Roslyn analyzer + C# code fixer that detects and eliminates redundant Regex.IsMatch guards that are immediately followed by Regex.Match with equivalent operands — causing the regex engine to run twice unnecessarily.

Before / After:

// Before
if (Regex.IsMatch(input, pattern))
{
    Match m = Regex.Match(input, pattern);
    // use m
}

// After
if (Regex.Match(input, pattern) is { Success: true } m)
{
    // use m
}

Analyzer (AvoidRedundantRegexIsMatchBeforeMatch.cs)

  • IOperation-based, language-agnostic (C# + VB)
  • Operand equivalence restricted to stable sources: locals, parameters, constants, readonly/const fields — properties, method calls, and mutable fields are intentionally excluded
  • Full intervening-write analysis covering assignments, ??=, ref/out mutations, and tuple deconstruction
  • Single-statement if bodies also checked for writes (not just block bodies)
  • Containig-type check via SymbolEqualityComparer rather than redundant GetMembers symbol sets

C# Fixer (CSharpAvoidRedundantRegexIsMatchBeforeMatch.Fixer.cs)

Two fix paths:

  • Local declarationMatch m = Regex.Match(...) inside the if body → replaced with is { Success: true } m pattern
  • Pre-declared variable — removes the declaration + inner assignment, rewrites the if condition with is pattern; includes safety check that the variable is not referenced after the if

Name-conflict detection covers locals, foreach variables, catch clauses, pattern designations, and lambda/local-function parameters.

Tests

83 tests covering: all static/instance/timeout overloads, both fix paths, no-diagnostic cases, VB smoke tests, named arguments, intervening writes, mutable receivers, ref/out mutations, readonly-field receiver reassignment, name-collision edge cases, and real-world patterns (else-if chains, foreach loops, const fields).

Original prompt

Address all remaining feedback and review comments on pull request #54071. The pull request, titled 'CA2028: Avoid redundant Regex.IsMatch before Regex.Match,' introduces an analyzer and code fixer for optimizing conditional code patterns where Regex.IsMatch is redundantly called before Regex.Match. Here's a summary of its current status:

Context:

  • The PR aims to prevent redundant Regex.IsMatch before Regex.Match and applies transformation to use the if (Regex.Match(input, pattern) is { Success: true } m) pattern.
  • Analyzer focuses on operation equivalence for stable sources and intervening write analysis.
  • It includes a C# code fixer, 82 tests for diagnostic/fix cases, and smoke tests for common patterns.

Key Areas to Address (from feedback and reviews):

  1. Refine operand equivalence checks to ensure robust scenarios for real-world cases.
  2. Address edge case scenarios highlighted in reviews, particularly intervening writes and mutable receivers.
  3. Ensure comprehensive test scenarios, which reviewers observed for gaps.
  4. Implement further best practices noted from prior comments regarding diagnostics, additional testing, and name alignment.

Tasks to Complete:

  • Integrate additional user-provided comments from reviewers in detail.
  • Recheck why some scenarios noted in reviews may trigger false positives/false negatives, and mitigate.
  • Run tests that are intended edge detection such mutable parameters.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Address feedback on dotnet/sdk pr 54071

Assistant: The pull request #54071 titled "CA2028: Avoid redundant Regex.IsMatch before Regex.Match" has feedback and reviews. Here's an overview of some key details:

  • The pull request addresses the pattern where Regex.IsMatch is called redundantly before Regex.Match. It implements fixes with an analyzer and 82 tests.
  • Associated reviewers include you (danmoseley), Youssef1313, and comments by the Copilot pull request reviewer bot.
  • You can view all the detailed reviews and feedback on GitHub here.

The API returned 30 review entries, but there might be additional review items. Would you like to explore the next page of reviews?

User: Go ahead address the feedback

Assistant: Work is underway to address all the feedback on pull request #54071. I'll update when the changes and fixes are complete!

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Address remaining feedback on PR #54071 Add CA2028: Avoid redundant Regex.IsMatch before Regex.Match Apr 26, 2026
Copilot AI requested a review from danmoseley April 26, 2026 20:55
@danmoseley
Copy link
Copy Markdown
Member

No I didn't want a new PR.

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.

2 participants