Skip to content

Remove null-forgiving operators and introduce TryCreate/Create pattern for Version class#7

Merged
Malcolmnixon merged 4 commits intomainfrom
copilot/remove-nullable-exclamation-operator
Feb 1, 2026
Merged

Remove null-forgiving operators and introduce TryCreate/Create pattern for Version class#7
Malcolmnixon merged 4 commits intomainfrom
copilot/remove-nullable-exclamation-operator

Conversation

Copy link
Contributor

Copilot AI commented Feb 1, 2026

Pull Request

Description

Removed all null-forgiving operators (!) from the codebase and introduced a better API design for the Version class following standard .NET conventions.

API Changes:

  • Added Version.TryCreate(string tag) that returns Version? (nullable) for cases where null is acceptable
  • Changed Version.Create(string tag) to return Version (non-nullable) and throw ArgumentException for invalid tags
  • This follows the standard .NET pattern (similar to int.TryParse vs int.Parse)

Source Code Changes:

  • GitHubRepoConnector.GetPullRequestsBetweenTagsAsync: Refactored conditional branches to explicitly check null state in each branch
  • GitHubRepoConnector.GetTagHistoryAsync: Updated to use Version.TryCreate for filtering non-version tags
  • MockRepoConnector.GetTagHistoryAsync: Updated to use Version.TryCreate for filtering non-version tags
  • Added defensive if (from == null || to == null) check in final else branch to satisfy compiler's flow analysis

Test Code Changes:

  • Simplified all test code by removing unnecessary Assert.IsNotNull() checks (15 occurrences removed)
  • Updated all test methods to use Version.Create() directly for known-valid version strings
  • Simplified mock classes to use Version.Create() directly in collection initializers
  • Added new test Version_TryCreate_ReturnsNullForInvalidTag to verify TryCreate returns null for invalid input
  • Added new test Version_Create_ThrowsForInvalidTag to verify Create throws ArgumentException for invalid input

Benefits:

  • Cleaner, more idiomatic .NET API design
  • More explicit intent: use TryCreate when filtering, Create when expecting valid input
  • Simplified test code without null checks for known-valid versions
  • No more null-forgiving operators in codebase

Type of Change

  • Code quality improvement
  • New feature (non-breaking change which adds functionality)

Related Issues

N/A

Pre-Submission Checklist

Before submitting this pull request, ensure you have completed the following:

Build and Test

  • Code builds successfully: dotnet build --configuration Release
  • All tests pass: dotnet test --configuration Release
  • Code produces zero warnings

Code Quality

  • Code formatting is correct: dotnet format --verify-no-changes
  • New code has appropriate XML documentation comments
  • Static analyzer warnings have been addressed

Quality Checks

Please run the following checks before submitting:

  • Spell checker passes: cspell "**/*.{md,cs}"
  • Markdown linter passes: markdownlint "**/*.md"
  • YAML linter passes: yamllint '**/*.{yml,yaml}'

Testing

  • Added unit tests for new functionality
  • Updated existing tests if behavior changed
  • All tests follow the AAA (Arrange, Act, Assert) pattern
  • Test coverage is maintained or improved

Documentation

  • Updated README.md (if applicable)
  • Updated ARCHITECTURE.md (if applicable)
  • Added code examples for new features (if applicable)
  • Updated requirements.yaml (if applicable)

Additional Notes

CodeQL security scan completed with 0 alerts. All 63 tests passing (increased from 61 with 2 new tests for TryCreate/Create behavior).

Original prompt

I'm not a fan of the C# "!" operator - I prefer code where the nullable is handled normally. Can you inspect the code to try and replace the exclamation operator with other approaches.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 1, 2026 22:59
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
Copilot AI changed the title [WIP] Refactor code to remove C# exclamation operator Remove null-forgiving operators in favor of explicit null handling Feb 1, 2026
Copilot AI requested a review from Malcolmnixon February 1, 2026 23:03
Copy link
Contributor

@Malcolmnixon Malcolmnixon left a comment

Choose a reason for hiding this comment

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

It seems many of the null checks are around Version.Create. Possibly introducing a Version.TryCreate which can return the nullabke, and have Version.Create return a non-nullable and throw on error.

Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 1, 2026

It seems many of the null checks are around Version.Create. Possibly introducing a Version.TryCreate which can return the nullabke, and have Version.Create return a non-nullable and throw on error.

Implemented in commit 03a0283. Added Version.TryCreate() (returns nullable) and changed Version.Create() to return non-nullable and throw ArgumentException on invalid input. This follows the standard .NET pattern and eliminated all null checks in test code. Source code now uses TryCreate for filtering tags and Create for known-valid inputs.

Copilot AI changed the title Remove null-forgiving operators in favor of explicit null handling Remove null-forgiving operators and introduce TryCreate/Create pattern for Version class Feb 1, 2026
Copilot AI requested a review from Malcolmnixon February 1, 2026 23:23
@Malcolmnixon Malcolmnixon marked this pull request as ready for review February 1, 2026 23:32
@Malcolmnixon Malcolmnixon merged commit 4e34a30 into main Feb 1, 2026
10 checks passed
@Malcolmnixon Malcolmnixon deleted the copilot/remove-nullable-exclamation-operator branch February 1, 2026 23:32
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