From 859b5f47f713693127878462125190b632048cc7 Mon Sep 17 00:00:00 2001 From: Thomas Clegg Date: Mon, 24 Aug 2026 19:38:57 -0500 Subject: [PATCH 1/2] style: idiomatic cleanups in small metadata/storage utility files is-null patterns, ??-style null checks, drop Yoda conditions, and expression-bodied trivial accessors across the smaller PhoneNumbers/ support files. No behavior change. --- .../AreaCodeMapStorageStrategy.cs | 10 +---- csharp/PhoneNumbers/DefaultMapStorage.cs | 15 ++----- csharp/PhoneNumbers/FlyweightMapStorage.cs | 43 +++++-------------- csharp/PhoneNumbers/LeniencyExtensions.cs | 6 +-- csharp/PhoneNumbers/LocaleData.cs | 2 +- csharp/PhoneNumbers/LocaleNames.cs | 4 +- csharp/PhoneNumbers/MetadataLoader.cs | 2 +- csharp/PhoneNumbers/MetadataManager.cs | 2 +- csharp/PhoneNumbers/MetadataSource.cs | 2 +- csharp/PhoneNumbers/PhoneNumberMatch.cs | 12 ++---- csharp/PhoneNumbers/TimezoneMapDataReader.cs | 18 ++++---- 11 files changed, 36 insertions(+), 80 deletions(-) diff --git a/csharp/PhoneNumbers/AreaCodeMapStorageStrategy.cs b/csharp/PhoneNumbers/AreaCodeMapStorageStrategy.cs index bba7bccfa..2b22ed952 100644 --- a/csharp/PhoneNumbers/AreaCodeMapStorageStrategy.cs +++ b/csharp/PhoneNumbers/AreaCodeMapStorageStrategy.cs @@ -60,19 +60,13 @@ public abstract class AreaCodeMapStorageStrategy /// The number of entries contained in the area code map. /// /// The number of entries contained in the area code map. - public int GetNumOfEntries() - { - return NumOfEntries; - } + public int GetNumOfEntries() => NumOfEntries; /// /// The set containing the possible lengths of prefixes. /// /// The set containing the possible lengths of prefixes. - public List GetPossibleLengths() - { - return PossibleLengths; - } + public List GetPossibleLengths() => PossibleLengths; public override string ToString() { diff --git a/csharp/PhoneNumbers/DefaultMapStorage.cs b/csharp/PhoneNumbers/DefaultMapStorage.cs index 1ae85151c..3457a6e20 100644 --- a/csharp/PhoneNumbers/DefaultMapStorage.cs +++ b/csharp/PhoneNumbers/DefaultMapStorage.cs @@ -32,20 +32,11 @@ public class DefaultMapStorage : AreaCodeMapStorageStrategy private int[] phoneNumberPrefixes; private string[] descriptions; - public override int GetPrefix(int index) - { - return phoneNumberPrefixes[index]; - } + public override int GetPrefix(int index) => phoneNumberPrefixes[index]; - public override int GetStorageSize() - { - return phoneNumberPrefixes.Length * sizeof(int) + descriptions.Sum(d => d.Length); - } + public override int GetStorageSize() => phoneNumberPrefixes.Length * sizeof(int) + descriptions.Sum(d => d.Length); - public override string GetDescription(int index) - { - return descriptions[index]; - } + public override string GetDescription(int index) => descriptions[index]; public override void ReadFromSortedMap(SortedDictionary sortedAreaCodeMap) { diff --git a/csharp/PhoneNumbers/FlyweightMapStorage.cs b/csharp/PhoneNumbers/FlyweightMapStorage.cs index db849d89a..c99da1f78 100644 --- a/csharp/PhoneNumbers/FlyweightMapStorage.cs +++ b/csharp/PhoneNumbers/FlyweightMapStorage.cs @@ -49,16 +49,10 @@ public class FlyweightMapStorage : AreaCodeMapStorageStrategy // The number of bytes used to store a phone number prefix. private int prefixSizeInBytes; - public override int GetPrefix(int index) - { - return ReadWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, index); - } + public override int GetPrefix(int index) => ReadWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, index); - public override int GetStorageSize() - { - return phoneNumberPrefixes.GetCapacity() + descriptionIndexes.GetCapacity() - + descriptionPool.Sum(d => d.Length); - } + public override int GetStorageSize() => + phoneNumberPrefixes.GetCapacity() + descriptionIndexes.GetCapacity() + descriptionPool.Sum(d => d.Length); /// /// This implementation returns the same string (same identity) when called for multiple indexes @@ -124,10 +118,8 @@ private void CreateDescriptionPool(HashSet descriptionsSet, SortedDictio /// /// Gets the minimum number of bytes that can be used to store the provided value. /// - private static int GetOptimalNumberOfBytesForValue(int value) - { - return value <= short.MaxValue ? ShortNumBytes : IntNumBytes; - } + private static int GetOptimalNumberOfBytesForValue(int value) => + value <= short.MaxValue ? ShortNumBytes : IntNumBytes; /// /// Stores the provided value to the provided byte buffer at the specified index using the provided wordSize in bytes. Note that only integer and short sizes are @@ -176,30 +168,15 @@ public ByteBuffer(int size) bytes = new byte[size]; } - public void PutShort(int offset, short value) - { - BinaryPrimitives.WriteInt16LittleEndian(bytes.AsSpan(offset), value); - } + public void PutShort(int offset, short value) => BinaryPrimitives.WriteInt16LittleEndian(bytes.AsSpan(offset), value); - public void PutInt(int offset, int value) - { - BinaryPrimitives.WriteInt32LittleEndian(bytes.AsSpan(offset), value); - } + public void PutInt(int offset, int value) => BinaryPrimitives.WriteInt32LittleEndian(bytes.AsSpan(offset), value); - public short GetShort(int offset) - { - return BinaryPrimitives.ReadInt16LittleEndian(bytes.AsSpan(offset)); - } + public short GetShort(int offset) => BinaryPrimitives.ReadInt16LittleEndian(bytes.AsSpan(offset)); - public int GetInt(int offset) - { - return BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(offset)); - } + public int GetInt(int offset) => BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(offset)); - public int GetCapacity() - { - return bytes.Length; - } + public int GetCapacity() => bytes.Length; } } } diff --git a/csharp/PhoneNumbers/LeniencyExtensions.cs b/csharp/PhoneNumbers/LeniencyExtensions.cs index 2494c1657..f769d9ca5 100644 --- a/csharp/PhoneNumbers/LeniencyExtensions.cs +++ b/csharp/PhoneNumbers/LeniencyExtensions.cs @@ -1,5 +1,5 @@ -using System; -using Leniency=PhoneNumbers.PhoneNumberUtil.Leniency; +using Leniency = PhoneNumbers.PhoneNumberUtil.Leniency; + namespace PhoneNumbers { public static class LeniencyExtensions @@ -9,7 +9,7 @@ public static bool Verify( PhoneNumber number, string candidate, PhoneNumberUtil util, - PhoneNumberMatcher matcher)=> + PhoneNumberMatcher matcher) => util.Verify(leniency, number, candidate, util, matcher); } } \ No newline at end of file diff --git a/csharp/PhoneNumbers/LocaleData.cs b/csharp/PhoneNumbers/LocaleData.cs index 4398ac1dc..374b5f6c0 100644 --- a/csharp/PhoneNumbers/LocaleData.cs +++ b/csharp/PhoneNumbers/LocaleData.cs @@ -40,7 +40,7 @@ private static ImmutableDictionary> foreach (var country in LocaleNames.SupportedCountries()) { var names = LocaleNames.ForCountry(country); - if (names != null) + if (names is not null) builder[country] = names.ToImmutableDictionary(); } return builder.ToImmutable(); diff --git a/csharp/PhoneNumbers/LocaleNames.cs b/csharp/PhoneNumbers/LocaleNames.cs index 97f2b293f..877aeac1b 100644 --- a/csharp/PhoneNumbers/LocaleNames.cs +++ b/csharp/PhoneNumbers/LocaleNames.cs @@ -56,12 +56,12 @@ internal static class LocaleNames /// the caller's job, as it was when this data was a single generated dictionary. /// internal static Dictionary ForCountry(string country) => - country == null ? null : Cache.GetOrAdd(country, LoadFactory); + country is null ? null : Cache.GetOrAdd(country, LoadFactory); private static Dictionary Load(string country) { using var raw = Assembly.GetManifestResourceStream(ResourcePrefix + country); - if (raw == null) + if (raw is null) return null; using var gz = new GZipStream(raw, CompressionMode.Decompress); diff --git a/csharp/PhoneNumbers/MetadataLoader.cs b/csharp/PhoneNumbers/MetadataLoader.cs index 7dc2e0e6a..9f57081b2 100644 --- a/csharp/PhoneNumbers/MetadataLoader.cs +++ b/csharp/PhoneNumbers/MetadataLoader.cs @@ -129,7 +129,7 @@ public EmbeddedResourceMetadataLoader(Assembly assembly, string resourcePrefix) // PhoneNumbers.MetadataBuilder). Decompress on the way out so callers see the plain // bin format they already expect. var raw = assembly.GetManifestResourceStream(resourcePrefix + fileName); - return raw == null ? null : new GZipStream(raw, CompressionMode.Decompress); + return raw is null ? null : new GZipStream(raw, CompressionMode.Decompress); } } } diff --git a/csharp/PhoneNumbers/MetadataManager.cs b/csharp/PhoneNumbers/MetadataManager.cs index 1b134cd39..c6b0368b0 100644 --- a/csharp/PhoneNumbers/MetadataManager.cs +++ b/csharp/PhoneNumbers/MetadataManager.cs @@ -56,7 +56,7 @@ private static MetadataSource CreateDefault(string filePrefix) /// Loader to use for both supplementary metadata file types. public static void SetMetadataLoader(IMetadataLoader loader) { - if (loader == null) throw new ArgumentNullException(nameof(loader)); + if (loader is null) throw new ArgumentNullException(nameof(loader)); alternateFormatsSource = new(loader, AlternateFormatsPrefix); shortNumberSource = new(loader, ShortNumberMetadataPrefix); } diff --git a/csharp/PhoneNumbers/MetadataSource.cs b/csharp/PhoneNumbers/MetadataSource.cs index a4f001e25..d58af1b0e 100644 --- a/csharp/PhoneNumbers/MetadataSource.cs +++ b/csharp/PhoneNumbers/MetadataSource.cs @@ -62,7 +62,7 @@ public MetadataSource(IMetadataLoader loader, string filePrefix) private PhoneMetadata? Load(string key) { using var stream = loader.LoadMetadata($"{filePrefix}_{key}"); - return stream == null ? null : BuildMetadataFromBin.ReadMetadata(stream); + return stream is null ? null : BuildMetadataFromBin.ReadMetadata(stream); } } } diff --git a/csharp/PhoneNumbers/PhoneNumberMatch.cs b/csharp/PhoneNumbers/PhoneNumberMatch.cs index 9fcf03089..2450048ec 100644 --- a/csharp/PhoneNumbers/PhoneNumberMatch.cs +++ b/csharp/PhoneNumbers/PhoneNumberMatch.cs @@ -33,9 +33,9 @@ public PhoneNumberMatch(int start, string rawString, PhoneNumber number) { if (start < 0) throw new ArgumentException("Start index must be >= 0.", nameof(start)); - if (rawString == null) + if (rawString is null) throw new ArgumentNullException(nameof(rawString)); - if (number == null) + if (number is null) throw new ArgumentNullException(nameof(number)); Start = start; RawString = rawString; @@ -50,8 +50,7 @@ public override bool Equals(object obj) { if (this == obj) return true; - var p = (obj as PhoneNumberMatch); - return p != null && RawString == p.RawString && Start == p.Start && Number.Equals(p.Number); + return obj is PhoneNumberMatch p && RawString == p.RawString && Start == p.Start && Number.Equals(p.Number); } public override int GetHashCode() @@ -63,9 +62,6 @@ public override int GetHashCode() return hash; } - public override string ToString() - { - return "PhoneNumberMatch [" + Start + "," + Length + ") " + RawString; - } + public override string ToString() => $"PhoneNumberMatch [{Start},{Length}) {RawString}"; } } diff --git a/csharp/PhoneNumbers/TimezoneMapDataReader.cs b/csharp/PhoneNumbers/TimezoneMapDataReader.cs index 862cbd06a..dd6dadd4d 100644 --- a/csharp/PhoneNumbers/TimezoneMapDataReader.cs +++ b/csharp/PhoneNumbers/TimezoneMapDataReader.cs @@ -13,10 +13,10 @@ internal static class TimezoneMapDataReader private static List LineReader(StreamReader reader, char fieldDelimiter = '|') { string line; - while (null != (line = reader.ReadLine())) + while ((line = reader.ReadLine()) != null) { line = line.Trim(); - if (line.Length < 1 || '#' == line[0]) + if (line.Length < 1 || line[0] == '#') continue; var indexOfDelimiter = line.IndexOf(fieldDelimiter); @@ -38,18 +38,16 @@ private static List LineReader(StreamReader reader, char fieldDelimiter /// internal static IDictionary GetPrefixMap(Stream fp, char[] splitters) { - if (null == fp) + if (fp is null) return ImmutableDictionary.Empty; var tmpMap = new SortedDictionary(); - using (var lines = new StreamReader(fp, Encoding.UTF8)) + using var lines = new StreamReader(fp, Encoding.UTF8); + List line; + while ((line = LineReader(lines)) != null) { - List line; - while (null != (line = LineReader(lines))) - { - var pnPrefix = line[0]; - tmpMap[long.Parse(pnPrefix, CultureInfo.InvariantCulture)] = line[1].Split(splitters, StringSplitOptions.RemoveEmptyEntries); - } + var pnPrefix = line[0]; + tmpMap[long.Parse(pnPrefix, CultureInfo.InvariantCulture)] = line[1].Split(splitters, StringSplitOptions.RemoveEmptyEntries); } return tmpMap; From bdd38941403dae1a82a9eff17aa91e53afbc23c4 Mon Sep 17 00:00:00 2001 From: Thomas Clegg Date: Wed, 26 Aug 2026 09:15:35 -0500 Subject: [PATCH 2/2] fix: use GetType() comparison in PhoneNumberMatch.Equals per CodeQL CodeQL (cs/equals-uses-as) flagged the "is" type check in Equals: it treats any subclass as a match, which can break Equals' symmetry contract if a subclass adds its own comparable state. Switch to a strict GetType() check, matching the standard fix for this pattern. Co-Authored-By: Claude Sonnet 5 --- csharp/PhoneNumbers/PhoneNumberMatch.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csharp/PhoneNumbers/PhoneNumberMatch.cs b/csharp/PhoneNumbers/PhoneNumberMatch.cs index 2450048ec..061b23911 100644 --- a/csharp/PhoneNumbers/PhoneNumberMatch.cs +++ b/csharp/PhoneNumbers/PhoneNumberMatch.cs @@ -50,7 +50,10 @@ public override bool Equals(object obj) { if (this == obj) return true; - return obj is PhoneNumberMatch p && RawString == p.RawString && Start == p.Start && Number.Equals(p.Number); + if (obj is null || GetType() != obj.GetType()) + return false; + var p = (PhoneNumberMatch)obj; + return RawString == p.RawString && Start == p.Start && Number.Equals(p.Number); } public override int GetHashCode()