Skip to content

style: idiomatic cleanups in PhoneNumberUtil.cs - #418

Merged
twcclegg merged 2 commits into
mainfrom
style/phonenumberutil-core
Aug 26, 2026
Merged

style: idiomatic cleanups in PhoneNumberUtil.cs#418
twcclegg merged 2 commits into
mainfrom
style/phonenumberutil-core

Conversation

@twcclegg

Copy link
Copy Markdown
Owner

Summary

Part of the ongoing idiomatic-C# cleanup sweep (see #409). Scoped to PhoneNumberUtil.cs only — the largest file in the repo, so kept conservative: only unambiguous, behavior-preserving wins.

  • == null / != null -> is null / is not null throughout (33 sites).
  • Constant-string .Equals(...) calls -> == / != (REGION_CODE_FOR_NON_GEO_ENTITY, UNKNOWN_REGION, an empty-string mobile-token check, and a NormalizeHelper() result comparison). Left PhoneNumber.Equals(...) object-equality calls untouched — those are genuine value equality, not string comparisons.
  • Fixed a stray K&R-brace IsPhoneContextValid to match the file's Allman convention.

Not fixing bugs, not chasing Java parity gaps (that was #408), not restructuring algorithms or renaming public members.

Test plan

  • dotnet build csharp/PhoneNumbers.slnx — 0 warnings (TreatWarningsAsErrors)
  • dotnet test csharp/PhoneNumbers.Test/PhoneNumbers.Test.csproj — 414/414 passing on net8.0 and net10.0

- == null / != null -> is null / is not null throughout, matching the
  pattern already used in most of this file and PR #409.
- Constant-string .Equals(...) calls (REGION_CODE_FOR_NON_GEO_ENTITY,
  UNKNOWN_REGION, an empty-string mobile-token check, and a
  NormalizeHelper() result comparison) -> == / !=.
- Fixed a stray K&R-brace IsPhoneContextValid to match the file's
  Allman convention.

No behavior change.
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.18182% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.34%. Comparing base (e75ae83) to head (b251b3c).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
csharp/PhoneNumbers/PhoneNumberUtil.cs 68.18% 2 Missing and 12 partials ⚠️

❌ Your patch check has failed because the patch coverage (68.18%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #418      +/-   ##
==========================================
- Coverage   87.42%   87.34%   -0.09%     
==========================================
  Files          41       41              
  Lines        3856     3855       -1     
  Branches      990      992       +2     
==========================================
- Hits         3371     3367       -4     
- Misses        283      284       +1     
- Partials      202      204       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

📊 Benchmark Results

Commit: b251b3c · Full run · Linux ubuntu-24.04-arm

Both sides were measured on the same runner in the same job, so the numbers are
comparable. Treat sub-percent differences as noise.

PR branch

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
InputDigitPerKeystroke 1000 4.368 ms 0.0110 ms 0.0098 ms 54.6875 3.88 MB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]     : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  Job-AMQORM : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Runtime=.NET 10.0  InvocationCount=1  IterationCount=20  
LaunchCount=1  RunStrategy=ColdStart  UnrollFactor=1  
WarmupCount=1  

Method Mean Error StdDev Allocated
CreateInstance 378.6 μs 102.2 μs 117.7 μs 119.48 KB
CreateInstanceAndLoadAllRegions 7,056.6 μs 396.3 μs 456.4 μs 1620.34 KB
FirstRegionLookup 445.4 μs 135.1 μs 155.5 μs 124.54 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ExtractPossibleNumber_CleanInput 1000 21.64 μs 0.022 μs 0.019 μs - -
ExtractPossibleNumber_WithLeadingJunk 1000 38.86 μs 0.064 μs 0.060 μs 0.6714 48360 B

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
FindNumbers_Valid 100 142.6 μs 0.35 μs 0.31 μs 0.9766 70.71 KB
FindNumbers_StrictGrouping 100 320.3 μs 0.50 μs 0.44 μs 1.4648 124.84 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
GetDescriptionForNumber 1000 1,464.32 μs 2.345 μs 2.079 μs 1.9531 196.59 KB
GetDisplayCountry 1000 18.52 μs 0.028 μs 0.023 μs 0.0916 7.56 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ParseValidateAndFormatPhoneNumbers 1000 2,557.9 μs 8.08 μs 7.16 μs 7.8125 577.71 KB
ParseOnly 1000 436.2 μs 0.68 μs 0.63 μs 4.8828 348.13 KB
ParseNationalFormat 1000 774.2 μs 0.95 μs 0.84 μs 5.8594 431.36 KB
ParseWithExtension 1000 1,107.5 μs 2.04 μs 1.91 μs 13.6719 957.38 KB
ValidateOnly 1000 772.7 μs 1.04 μs 0.92 μs - 41.11 KB
FormatOnly 1000 1,112.4 μs 5.85 μs 5.18 μs 1.9531 187.92 KB
PR base

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
InputDigitPerKeystroke 1000 4.346 ms 0.0094 ms 0.0088 ms 54.6875 3.88 MB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]     : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  Job-AMQORM : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Runtime=.NET 10.0  InvocationCount=1  IterationCount=20  
LaunchCount=1  RunStrategy=ColdStart  UnrollFactor=1  
WarmupCount=1  

Method Mean Error StdDev Allocated
CreateInstance 386.2 μs 106.0 μs 122.1 μs 119.48 KB
CreateInstanceAndLoadAllRegions 7,049.3 μs 416.8 μs 480.0 μs 1620.34 KB
FirstRegionLookup 452.8 μs 127.2 μs 146.5 μs 124.54 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ExtractPossibleNumber_CleanInput 1000 20.88 μs 0.018 μs 0.016 μs - -
ExtractPossibleNumber_WithLeadingJunk 1000 38.43 μs 0.076 μs 0.068 μs 0.6714 48360 B

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
FindNumbers_Valid 100 141.8 μs 0.22 μs 0.21 μs 0.9766 70.71 KB
FindNumbers_StrictGrouping 100 325.5 μs 0.63 μs 0.59 μs 1.4648 124.84 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
GetDescriptionForNumber 1000 1,425.20 μs 6.320 μs 5.912 μs 1.9531 196.59 KB
GetDisplayCountry 1000 18.54 μs 0.025 μs 0.022 μs 0.0916 7.56 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.400
  [Host]    : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.11 (10.0.11, 10.0.1126.37416), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ParseValidateAndFormatPhoneNumbers 1000 2,572.3 μs 7.28 μs 6.81 μs 7.8125 577.71 KB
ParseOnly 1000 437.2 μs 1.17 μs 1.09 μs 4.8828 348.13 KB
ParseNationalFormat 1000 766.3 μs 1.75 μs 1.55 μs 5.8594 431.36 KB
ParseWithExtension 1000 1,119.6 μs 2.55 μs 2.26 μs 13.6719 957.38 KB
ValidateOnly 1000 770.5 μs 1.66 μs 1.39 μs - 41.11 KB
FormatOnly 1000 1,096.6 μs 2.97 μs 2.78 μs 1.9531 187.92 KB

FormatInOriginalFormat was missing the null guard on formatRule that
upstream Java has before the default-case switch dereferences it
(formatRule can still be null here per Java's own comment on this
edge case).

MaybeStripNationalPrefixAndCarrierCode's numberLength fallback
dereferenced `number` directly while the rest of the method already
treats it as nullable (`number?.Remove(...)`, `number is not null`),
so make that one access consistent with the same guard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@twcclegg
twcclegg merged commit 5e508c0 into main Aug 26, 2026
7 of 8 checks passed
@twcclegg
twcclegg deleted the style/phonenumberutil-core branch August 26, 2026 14:33
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