Skip to content

Conversation

@atifaziz
Copy link
Collaborator

Description

This PR upgrades the project from C# 10 to C# 14 and systematically modernizes the codebase by adopting the latest C# language features where there's the greatest immediate benefit. The changes are purely syntactic and do not alter the runtime behavior of the library.

Overview

The modernization effort focuses on improving code readability and maintainability by leveraging C# language enhancements since version 10. All examples, source code, and tests have been updated to use modern C# idioms while maintaining backward compatibility at the API level.

Key Changes

Language Version Update

  • Upgraded LangVersion from 10 to 14 in Directory.Build.props to enable all modern C# features

Raw String Literals (C# 11)

  • Replaced traditional verbatim strings (@"...") with raw string literals ("""...""") throughout the codebase
  • Particularly impactful in docopt usage strings and multiline text, eliminating escape sequences and improving readability
  • Updated all example programs and test cases to use the cleaner syntax

Collection Expressions (C# 12)

  • Modernized array and collection initializations using collection expression syntax ([])
  • Replaced new[] { ... } with [...] for more concise array declarations
  • Updated empty collection creation patterns (e.g., Array.Empty<T>()[])

Primary Constructors (C# 12)

  • Converted numerous classes to use primary constructors, reducing boilerplate
  • Particularly effective in internal classes, test utilities, and sealed types
  • Added #pragma warning disable IDE0290 in cases where protected constructors cannot use primary syntax

Extension Types/Members (C# 14)

  • Refactored extension method patterns to use the new extension(Type) syntax
  • Makes extension grouping & relationships more obvious
  • Applied to ParseResultExtensions, ApplicationResultExtensions, and various helper methods

Pattern Matching Enhancements

  • Replaced StartsWith/EndsWith checks with list patterns (e.g., ['-', '-', ..] for strings starting with "--")
  • Switched multiple if-else chains to switch expressions with pattern matching
  • More expressive and performant string validation logic

String Manipulation

  • Replaced Substring calls with range syntax ([i..], [..i], [i..j])
  • Cleaner and less error-prone string slicing

With Expressions

  • Used with expressions for record-like updates (e.g., updating node values)
  • Maintains immutability patterns more naturally

Field-Backed Properties

  • Converted some auto-properties to field-backed properties where appropriate
  • Simplified parameter-to-field assignments in primary constructors

Type Pattern Refinements

  • Replaced conditional cast patterns (is T ? T : default) with pattern expressions (as T)
  • Simplified nullable reference handling

Syntactic Cleanup

  • Removed redundant interface bodies (; for empty interfaces)
  • Removed unnecessary null-coalescing patterns
  • Simplified Boolean and type checks

Testing

All existing tests pass without modification to their logic. The changes are purely syntactic:

  • Language-agnostic test suite (testcases.docopt) validates library behavior unchanged
  • Source generator tests verify correct code generation with modern syntax
  • Integration tests (Naval Fate examples) confirm real-world usage patterns

@atifaziz atifaziz merged commit c83c86c into docopt:master Dec 25, 2025
2 checks passed
@atifaziz atifaziz deleted the up/cs14 branch December 25, 2025 12:38
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.

1 participant