Skip to content

Commit ca003a4

Browse files
Fix nullability warnings
1 parent 003a768 commit ca003a4

File tree

5 files changed

+57
-44
lines changed

5 files changed

+57
-44
lines changed

src/TimeZoneNames.DataBuilder/DataExtractor.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ public void SaveData(string outputFilePath)
3939
JsonSerializer.Serialize(compressedStream, _data);
4040
}
4141

42-
private TzdbDateTimeZoneSource _tzdbSource;
43-
private IDateTimeZoneProvider _tzdbProvider;
42+
private TzdbDateTimeZoneSource _tzdbSource = null!;
43+
private IDateTimeZoneProvider _tzdbProvider = null!;
4444

4545
private void LoadData()
4646
{
@@ -154,7 +154,7 @@ private void LoadSelectionZones()
154154
var precedence = File.ReadAllLines(Path.Combine("data", "zone-precedence.txt"));
155155

156156
var splitPoints = GetAllZoneSplitPoints();
157-
IList<string> last = null;
157+
IList<string>? last = null;
158158
var useConsole = TryHideConsoleCursor();
159159
for (var i = splitPoints.Count - 1; i >= 0; i--)
160160
{
@@ -227,7 +227,7 @@ private IList<string> GetSelectionZones(Instant fromInstant, string[] precedence
227227
Location = _tzdbSource.ZoneLocations!.FirstOrDefault(l => l.ZoneId == x)
228228
})
229229
.Where(x => x.Location != null)
230-
.GroupBy(x => new { x.Location.CountryCode, Hash = GetIntervalsHash(x.Intervals) })
230+
.GroupBy(x => new { x.Location?.CountryCode, Hash = GetIntervalsHash(x.Intervals) })
231231
.Select(g =>
232232
{
233233
var ids = g.Select(z => z.Id).ToArray();
@@ -345,7 +345,7 @@ private void LoadMetaZonesFromFile(string path)
345345
private void LoadLanguages()
346346
{
347347
var languages = Directory.GetFiles(Path.Combine(_cldrPath, "common", "main"))
348-
.Select(Path.GetFileName)
348+
.Select(s => Path.GetFileName(s)!)
349349
.Select(x => x.Substring(0, x.Length - 4));
350350

351351
Parallel.ForEach(languages, LoadLanguage);
@@ -521,9 +521,9 @@ private void LoadDisplayNames()
521521

522522
foreach (var item in languages.AsArray())
523523
{
524-
var locale = item["Locale"]!.GetValue<string>().Replace("-", "_");
524+
var locale = item!["Locale"]!.GetValue<string>().Replace("-", "_");
525525
var list = item["TimeZones"]!.AsObject()
526-
.Select(o => new KeyValuePair<string, string>(o.Key, (string) o.Value))
526+
.Select(o => new KeyValuePair<string, string>(o.Key, (string) o.Value!))
527527
.ToList();
528528

529529
// Base offset change for Jordan, reflected in Windows, not yet in tzinfo.json

src/TimeZoneNames/OrderedDictionary.cs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
using System.Collections;
22
using System.Collections.Specialized;
3+
using System.Diagnostics.CodeAnalysis;
34

45
namespace TimeZoneNames;
56

67
internal class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>
8+
where TKey : notnull
79
{
810
// TODO: Find a better implementation.
911
// We might only need an IReadOnlyDictionary<TKey, TValue> but we want to preserve insertion order.
1012
private readonly OrderedDictionary _dictionary;
1113

12-
public OrderedDictionary(int capacity = 0, IEqualityComparer<TKey> equalityComparer = default)
14+
public OrderedDictionary(int capacity = 0, IEqualityComparer<TKey>? equalityComparer = default)
1315
{
14-
_dictionary = new OrderedDictionary(capacity, (IEqualityComparer) equalityComparer);
16+
_dictionary = new OrderedDictionary(capacity, (IEqualityComparer?) equalityComparer);
1517
}
1618

1719
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => _dictionary
1820
.Cast<DictionaryEntry>()
19-
.Select(x => new KeyValuePair<TKey, TValue>((TKey) x.Key, (TValue) x.Value))
21+
.Select(x => new KeyValuePair<TKey, TValue>((TKey) x.Key, (TValue) x.Value!))
2022
.GetEnumerator();
2123

2224
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
@@ -34,9 +36,9 @@ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
3436
{
3537
if (i >= arrayIndex && i < array.Length)
3638
{
37-
array[i] = new KeyValuePair<TKey, TValue>((TKey) entry.Key, (TValue) entry.Value);
39+
array[i] = new KeyValuePair<TKey, TValue>((TKey) entry.Key, (TValue) entry.Value!);
3840
}
39-
41+
4042
i++;
4143
}
4244
}
@@ -62,22 +64,24 @@ public bool Remove(TKey key)
6264
return found;
6365
}
6466

65-
public bool TryGetValue(TKey key, out TValue value)
67+
#pragma warning disable CS8767
68+
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
69+
#pragma warning restore CS8767
6670
{
6771
var obj = _dictionary[key];
6872
if (obj == null)
6973
{
7074
value = default;
7175
return false;
7276
}
73-
77+
7478
value = (TValue) obj;
7579
return true;
7680
}
7781

7882
public TValue this[TKey key]
7983
{
80-
get => (TValue) _dictionary[key];
84+
get => _dictionary[key] is { } value ? (TValue) value : throw new KeyNotFoundException();
8185
set => _dictionary[key] = value;
8286
}
8387

@@ -90,21 +94,24 @@ internal static class OrderedDictionaryExtensions
9094
{
9195
public static OrderedDictionary<TKey, TValue> ToOrderedDictionary<TKey, TValue>(
9296
this ICollection<KeyValuePair<TKey, TValue>> items,
93-
IEqualityComparer<TKey> comparer = default)
97+
IEqualityComparer<TKey>? comparer = default)
98+
where TKey : notnull
9499
{
95100
var result = new OrderedDictionary<TKey, TValue>(items.Count, comparer);
96101
foreach (var item in items)
97102
{
98103
result.Add(item);
99104
}
105+
100106
return result;
101107
}
102108

103109
public static OrderedDictionary<TKey, TValue> ToOrderedDictionary<TSource, TKey, TValue>(
104110
this ICollection<TSource> items,
105111
Func<TSource, TKey> keySelector,
106112
Func<TSource, TValue> valueSelector,
107-
IEqualityComparer<TKey> comparer = default)
113+
IEqualityComparer<TKey>? comparer = default)
114+
where TKey : notnull
108115
{
109116
var result = new OrderedDictionary<TKey, TValue>(items.Count, comparer);
110117
foreach (var item in items)
@@ -113,18 +120,21 @@ public static OrderedDictionary<TKey, TValue> ToOrderedDictionary<TSource, TKey,
113120
var value = valueSelector(item);
114121
result.Add(key, value);
115122
}
123+
116124
return result;
117125
}
118-
126+
119127
public static OrderedDictionary<TKey, TValue> ToOrderedDictionary<TKey, TValue>(
120128
this IEnumerable<KeyValuePair<TKey, TValue>> items,
121-
IEqualityComparer<TKey> comparer = default) =>
122-
items.ToList().ToOrderedDictionary(comparer);
129+
IEqualityComparer<TKey>? comparer = default)
130+
where TKey : notnull
131+
=> items.ToList().ToOrderedDictionary(comparer);
123132

124133
public static OrderedDictionary<TKey, TValue> ToOrderedDictionary<TSource, TKey, TValue>(
125134
this IEnumerable<TSource> items,
126135
Func<TSource, TKey> keySelector,
127136
Func<TSource, TValue> valueSelector,
128-
IEqualityComparer<TKey> comparer = default) =>
129-
items.ToList().ToOrderedDictionary(keySelector, valueSelector, comparer);
137+
IEqualityComparer<TKey>? comparer = default)
138+
where TKey : notnull
139+
=> items.ToList().ToOrderedDictionary(keySelector, valueSelector, comparer);
130140
}

src/TimeZoneNames/TZNames.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ public static IDictionary<string, string> GetTimeZonesForCountry(string countryC
8484
Id = x,
8585
Name = GetNames(x, langKey, false).Generic
8686
})
87-
.ToDictionary(x => x.Id, x => x.Name, StringComparer.OrdinalIgnoreCase);
87+
.Where(x => x.Name != null)
88+
.ToDictionary(x => x.Id, x => x.Name!, StringComparer.OrdinalIgnoreCase);
8889

8990
// Append city names only when needed to differentiate zones with the same name
9091
foreach (var group in results.GroupBy(x => x.Value).Where(x => x.Count() > 1).ToArray())
@@ -169,7 +170,7 @@ private static IDictionary<string, string> GetFixedTimeZoneNames(string language
169170

170171
foreach (var zone in zones)
171172
{
172-
var name = GetNames(zone, langKey, abbreviations).Generic;
173+
var name = GetNames(zone, langKey, abbreviations).Generic!;
173174
results.Add(zone, name);
174175
}
175176

@@ -250,7 +251,7 @@ public static IDictionary<string, string> GetCountryNames(string languageCode)
250251
/// <param name="timeZoneId">An IANA or Windows time zone identifier.</param>
251252
/// <param name="languageCode">The IETF language tag (culture code) to use when localizing the display names.</param>
252253
/// <returns>A display name associated with this time zone.</returns>
253-
public static string GetDisplayNameForTimeZone(string timeZoneId, string languageCode)
254+
public static string? GetDisplayNameForTimeZone(string timeZoneId, string languageCode)
254255
{
255256
var langKey = GetLanguageKey(languageCode, true);
256257
if (langKey == null)
@@ -265,8 +266,8 @@ public static string GetDisplayNameForTimeZone(string timeZoneId, string languag
265266
return displayName;
266267
}
267268

268-
if (TZConvert.TryIanaToWindows(timeZoneId, out timeZoneId) &&
269-
displayNames.TryGetValue(timeZoneId, out displayName))
269+
if (TZConvert.TryIanaToWindows(timeZoneId, out var windowsTimeZoneId) &&
270+
displayNames.TryGetValue(windowsTimeZoneId, out displayName))
270271
{
271272
return displayName;
272273
}
@@ -287,7 +288,7 @@ public static IDictionary<string, string> GetDisplayNames(string languageCode, b
287288
{
288289
throw new ArgumentException("Invalid Language Code", nameof(languageCode));
289290
}
290-
291+
291292
var displayNames = Data.DisplayNames[langKey]
292293
.Where(x => !TimeZoneData.ObsoleteWindowsZones.Contains(x.Key))
293294
.ToList();
@@ -374,7 +375,7 @@ private static string GetLanguageKey(string languageCode, bool forDisplayNames =
374375
}
375376
}
376377

377-
private static string GetLanguageSubkey(string languageKey)
378+
private static string? GetLanguageSubkey(string languageKey)
378379
{
379380
var keyParts = languageKey.Split('_');
380381
if (keyParts.Length == 1)
@@ -387,10 +388,11 @@ private static string GetLanguageSubkey(string languageKey)
387388

388389
private static void SearchLanguages(string languageKey, TimeZoneValues values, Action<string> action)
389390
{
390-
while (languageKey != null && (values.Generic == null || values.Standard == null || values.Daylight == null))
391+
var langKey = languageKey;
392+
while (langKey != null && (values.Generic == null || values.Standard == null || values.Daylight == null))
391393
{
392-
action(languageKey);
393-
languageKey = GetLanguageSubkey(languageKey);
394+
action(langKey);
395+
langKey = GetLanguageSubkey(langKey);
394396
}
395397
}
396398

@@ -401,15 +403,16 @@ private static string GetCldrCanonicalId(string timeZoneId)
401403

402404
private static string GetCityName(string timeZoneId, string languageKey)
403405
{
404-
while (languageKey != null)
406+
var langKey = languageKey;
407+
while (langKey != null)
405408
{
406-
var data = Data.CldrLanguageData[languageKey];
409+
var data = Data.CldrLanguageData[langKey];
407410
if (data.CityNames.TryGetValue(timeZoneId, out var cityName))
408411
{
409412
return cityName;
410413
}
411414

412-
languageKey = GetLanguageSubkey(languageKey);
415+
langKey = GetLanguageSubkey(langKey);
413416
}
414417

415418
return timeZoneId.Split('/').Last().Replace("_", " ");
@@ -526,7 +529,7 @@ private static TimeZoneValues GetNames(string timeZoneId, string languageKey, bo
526529
}
527530
}
528531

529-
string regionName = null;
532+
string? regionName = null;
530533
if (country != null)
531534
{
532535
SearchLanguages(languageKey, values, key =>
@@ -620,12 +623,12 @@ private static TimeZoneValues GetNames(string timeZoneId, string languageKey, bo
620623
return values;
621624
}
622625

623-
private static string GetMetazone(string timeZoneId)
626+
private static string? GetMetazone(string timeZoneId)
624627
{
625628
return Data.CldrMetazones.TryGetValue(timeZoneId, out var metaZone) ? metaZone : null;
626629
}
627630

628-
private static bool PopulateDirectValues(string langKey, TimeZoneValues values, string timeZoneId, string metaZone,
631+
private static bool PopulateDirectValues(string langKey, TimeZoneValues values, string timeZoneId, string? metaZone,
629632
bool abbreviations)
630633
{
631634
if (!Data.CldrLanguageData.ContainsKey(langKey))

src/TimeZoneNames/TimeZoneData.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ public static TimeZoneData Load()
5656

5757
internal class CldrLanguageData
5858
{
59-
public TimeZoneValues Formats { get; set; }
59+
public TimeZoneValues? Formats { get; set; }
6060

61-
public string FallbackFormat { get; set; }
61+
public string? FallbackFormat { get; set; }
6262

6363
public Dictionary<string, TimeZoneValues> ShortNames { get; set; } = new(StringComparer.OrdinalIgnoreCase);
6464

@@ -81,7 +81,7 @@ internal class CldrLanguageData
8181

8282
internal class TimeZoneSelectionData
8383
{
84-
public string Id { get; set; }
84+
public string Id { get; set; } = null!;
8585

8686
public DateTime ThresholdUtc { get; set; }
8787
}

src/TimeZoneNames/TimeZoneValues.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ public class TimeZoneValues
1111
/// The time zone name that generically applies.
1212
/// </summary>
1313
[JsonInclude]
14-
public string Generic { get; internal set; }
14+
public string? Generic { get; internal set; }
1515

1616
/// <summary>
1717
/// The time zone name that applies during standard time.
1818
/// </summary>
1919
[JsonInclude]
20-
public string Standard { get; internal set; }
20+
public string? Standard { get; internal set; }
2121

2222
/// <summary>
2323
/// The time zone name that applies during daylight saving time.
2424
/// </summary>
2525
[JsonInclude]
26-
public string Daylight { get; internal set; }
26+
public string? Daylight { get; internal set; }
2727
}

0 commit comments

Comments
 (0)