Nullable: globalization remainder (dotnet/coreclr#23526)
authorKrzysztof Wicher <mordotymoja@gmail.com>
Tue, 2 Apr 2019 16:07:08 +0000 (09:07 -0700)
committerGitHub <noreply@github.com>
Tue, 2 Apr 2019 16:07:08 +0000 (09:07 -0700)
* Nullable: remainder of globalization

* annotate windows specific files

* add TODO-NULLABLE next to TODO suggesting comments

* fixes after merging other globalization annotations, apply feedback

* fix windows

* address feedback

* fix windows

* fixes

* apply feedback

* remove workaround

* s_Invariant?, couple of Debug.Asserts

Commit migrated from https://github.com/dotnet/coreclr/commit/d073a1721e4893d8ebf7c384f1d6ee6bb9711f16

50 files changed:
src/libraries/System.Private.CoreLib/src/System/Globalization/Calendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/ChineseLunisolarCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Invariant.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/CultureNotFoundException.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/DaylightTime.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationExtensions.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendarHelper.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/HebrewCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/HebrewNumber.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/HijriCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/ISOWeek.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/IdnMapping.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/IdnMapping.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/IdnMapping.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/InternalGlobalizationHelper.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseLunisolarCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/JulianCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/KoreanCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/KoreanLunisolarCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/LocaleData.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/PersianCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/RegionInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/StringInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanLunisolarCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/ThaiBuddhistCalendar.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/UmAlQuraCalendar.cs

index c54e558..aa9a071 100644 (file)
@@ -148,8 +148,8 @@ namespace System.Globalization
         {
             // From ECMA CLI spec, Partition III, section 3.27:
             //
-            // If overflow occurs converting a floating-point type to an integer, or if the floating-point value 
-            // being converted to an integer is a NaN, the value returned is unspecified. 
+            // If overflow occurs converting a floating-point type to an integer, or if the floating-point value
+            // being converted to an integer is a NaN, the value returned is unspecified.
             //
             // Based upon this, this method should be performing the comparison against the double
             // before attempting a cast. Otherwise, the result is undefined.
@@ -323,7 +323,7 @@ namespace System.Globalization
         /// Get the list of era values.
         /// </summary>
         /// <returns>The int array of the era names supported in this calendar or null if era is not used.</returns>
-        public abstract int[]? Eras { get; }
+        public abstract int[] Eras { get; }
 
         // Returns the hour part of the specified DateTime. The returned value is an
         // integer between 0 and 23.
@@ -418,7 +418,7 @@ namespace System.Globalization
             int day;
 
             int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
-            
+
             // Calculate the number of days between the first day of year (1/1) and the first day of the week.
             // This value will be a positive value from 0 ~ 6.  We call this value as "offset".
             //
@@ -465,7 +465,7 @@ namespace System.Globalization
             // Otherwise, the specified time falls on the week of previous year.
             // Call this method again by passing the last day of previous year.
             // the last day of the previous year may "underflow" to no longer be a valid date time for
-            // this calendar if we just subtract so we need the subclass to provide us with 
+            // this calendar if we just subtract so we need the subclass to provide us with
             // that information
             if (time <= MinSupportedDateTime.AddDays(dayOfYear))
             {
index 3121702..e57e0c5 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Security;
@@ -35,22 +36,25 @@ namespace System.Globalization
         private bool LoadCalendarDataFromSystem(string localeName, CalendarId calendarId)
         {
             bool result = true;
-            result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName);
-            result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay);
+            // TODO-NULLABLE: these can return null but are later replaced with String.Empty or other non-nullable value
+            result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName!);
+            result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay!);
             this.sMonthDay = NormalizeDatePattern(this.sMonthDay);
 
-            result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates);
-            result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates);
-            result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths);
-            result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames);
-            result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames);
-            result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames);
+            result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates!);
+            result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates!);
+            result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths!);
+            result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames!);
+            result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames!);
+            result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames!);
 
-            string leapHebrewMonthName = null;
-            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames, ref leapHebrewMonthName);
+            string? leapHebrewMonthName = null;
+            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames!, ref leapHebrewMonthName);
             if (leapHebrewMonthName != null)
-            {              
-                // In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7              
+            {
+                Debug.Assert(this.saMonthNames != null);
+
+                // In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7
                 Debug.Assert(calendarId == CalendarId.HEBREW && saMonthNames.Length == 13);
                 saLeapYearMonthNames = (string[]) saMonthNames.Clone();
                 saLeapYearMonthNames[6] = leapHebrewMonthName;
@@ -62,12 +66,12 @@ namespace System.Globalization
                 saMonthNames[6] = leapHebrewMonthName;
 
             }
-            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames, ref leapHebrewMonthName);
-            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames, ref leapHebrewMonthName);
-            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames, ref leapHebrewMonthName);
+            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames!, ref leapHebrewMonthName);
+            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames!, ref leapHebrewMonthName);
+            result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames!, ref leapHebrewMonthName);
 
-            result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames);
-            result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames);
+            result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames!);
+            result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames!);
 
             return result;
         }
@@ -122,7 +126,7 @@ namespace System.Globalization
                 out calendarString);
         }
 
-        private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] datePatterns)
+        private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? datePatterns)
         {
             datePatterns = null;
 
@@ -171,14 +175,14 @@ namespace System.Globalization
             {
                 if (s[index] == '\'')
                 {
-                    do 
+                    do
                     {
                         modifiedPattern[index] = s[index];
                         index++;
                     } while (index < s.Length && s[index] != '\'');
 
                     if (index >= s.Length)
-                        return;                 
+                        return;
                 }
                 else if (s[index] == 'y')
                 {
@@ -347,7 +351,7 @@ namespace System.Globalization
             return index - startIndex;
         }
 
-        private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames, ref string leapHebrewMonthName)
+        private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? monthNames, ref string? leapHebrewMonthName)
         {
             monthNames = null;
 
@@ -366,13 +370,13 @@ namespace System.Globalization
                 if (callbackContext.Results.Count > 13)
                 {
                     Debug.Assert(calendarId == CalendarId.HEBREW && callbackContext.Results.Count == 14);
-                    
+
                     if (calendarId == CalendarId.HEBREW)
                     {
                         leapHebrewMonthName = callbackContext.Results[13];
                     }
                     callbackContext.Results.RemoveRange(13, callbackContext.Results.Count - 13);
-                }                
+                }
 
                 monthNames = callbackContext.Results.ToArray();
             }
@@ -380,22 +384,22 @@ namespace System.Globalization
             return result;
         }
 
-        private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames)
+        private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? eraNames)
         {
             bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames);
 
             // .NET expects that only the Japanese calendars have more than 1 era.
             // So for other calendars, only return the latest era.
-            if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames.Length > 0)
+            if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames?.Length > 0)
             {
-                string[] latestEraName = new string[] { eraNames[eraNames.Length - 1] };
+                string[] latestEraName = new string[] { eraNames![eraNames.Length - 1] };
                 eraNames = latestEraName;
             }
 
             return result;
         }
 
-        internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData)
+        internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? calendarData)
         {
             calendarData = null;
 
index 56ddf75..131dd6b 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 
 namespace System.Globalization
@@ -12,33 +13,37 @@ namespace System.Globalization
     //
     //  NOTE: Calendars depend on the locale name that creates it.  Only a few
     //        properties are available without locales using CalendarData.GetCalendar(CalendarData)
-
+    //
+    // TODO-NULLABLE: this class requires refactoring for proper annotations
+    //                currently from user of this class all fields are non-nullable.
+    //                To avoid potential breaking changes lots of workaround have
+    //                been used to suppress errors
     internal partial class CalendarData
     {
         // Max calendars
         internal const int MAX_CALENDARS = 23;
 
         // Identity
-        internal string sNativeName; // Calendar Name for the locale
+        internal string sNativeName = null!; // Calendar Name for the locale
 
         // Formats
-        internal string[] saShortDates; // Short Data format, default first
-        internal string[] saYearMonths; // Year/Month Data format, default first
-        internal string[] saLongDates; // Long Data format, default first
-        internal string sMonthDay; // Month/Day format
+        internal string[] saShortDates = null!; // Short Data format, default first
+        internal string[] saYearMonths = null!; // Year/Month Data format, default first
+        internal string[] saLongDates = null!; // Long Data format, default first
+        internal string sMonthDay = null!; // Month/Day format
 
         // Calendar Parts Names
-        internal string[] saEraNames; // Names of Eras
-        internal string[] saAbbrevEraNames; // Abbreviated Era Names
-        internal string[] saAbbrevEnglishEraNames; // Abbreviated Era Names in English
-        internal string[] saDayNames; // Day Names, null to use locale data, starts on Sunday
-        internal string[] saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
-        internal string[] saSuperShortDayNames; // Super short Day of week names
-        internal string[] saMonthNames; // Month Names (13)
-        internal string[] saAbbrevMonthNames; // Abbrev Month Names (13)
-        internal string[] saMonthGenitiveNames; // Genitive Month Names (13)
-        internal string[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13)
-        internal string[] saLeapYearMonthNames; // Multiple strings for the month names in a leap year.
+        internal string[] saEraNames = null!; // Names of Eras
+        internal string[] saAbbrevEraNames = null!; // Abbreviated Era Names
+        internal string[] saAbbrevEnglishEraNames = null!; // Abbreviated Era Names in English
+        internal string[] saDayNames = null!; // Day Names, null to use locale data, starts on Sunday
+        internal string[] saAbbrevDayNames = null!; // Abbrev Day Names, null to use locale data, starts on Sunday
+        internal string[] saSuperShortDayNames = null!; // Super short Day of week names
+        internal string[] saMonthNames = null!; // Month Names (13)
+        internal string[] saAbbrevMonthNames = null!; // Abbrev Month Names (13)
+        internal string[] saMonthGenitiveNames = null!; // Genitive Month Names (13)
+        internal string[] saAbbrevMonthGenitiveNames = null!; // Genitive Abbrev Month Names (13)
+        internal string[] saLeapYearMonthNames = null!; // Multiple strings for the month names in a leap year.
 
         // Integers at end to make marshaller happier
         internal int iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
@@ -51,7 +56,9 @@ namespace System.Globalization
         internal static readonly CalendarData Invariant = CreateInvariant();
 
         // Private constructor
-        private CalendarData() { }
+        private CalendarData()
+        {
+        }
 
         // Invariant factory
         private static CalendarData CreateInvariant()
@@ -165,7 +172,7 @@ namespace System.Globalization
                 this.saAbbrevEnglishEraNames = new string[] { "" };
             }
 
-            // Japanese is the only thing with > 1 era.  Its current era # is how many ever 
+            // Japanese is the only thing with > 1 era.  Its current era # is how many ever
             // eras are in the array.  (And the others all have 1 string in the array)
             this.iCurrentEra = this.saEraNames.Length;
         }
@@ -177,7 +184,7 @@ namespace System.Globalization
             {
                 // For Localized Gregorian we really expect the data from the OS.
                 case CalendarId.GREGORIAN:
-                    // Fallback for CoreCLR < Win7 or culture.dll missing            
+                    // Fallback for CoreCLR < Win7 or culture.dll missing
                     if (this.saEraNames == null || this.saEraNames.Length == 0 || string.IsNullOrEmpty(this.saEraNames[0]))
                     {
                         this.saEraNames = new string[] { "A.D." };
@@ -260,7 +267,7 @@ namespace System.Globalization
             {
                 // For Localized Gregorian we really expect the data from the OS.
                 case CalendarId.GREGORIAN:
-                    // Fallback for CoreCLR < Win7 or culture.dll missing            
+                    // Fallback for CoreCLR < Win7 or culture.dll missing
                     if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || string.IsNullOrEmpty(this.saAbbrevEraNames[0]))
                     {
                         this.saAbbrevEraNames = new string[] { "AD" };
@@ -320,7 +327,7 @@ namespace System.Globalization
             //
             // Get a calendar.
             // Unfortunately we depend on the locale in the OS, so we need a locale
-            // no matter what.  So just get the appropriate calendar from the 
+            // no matter what.  So just get the appropriate calendar from the
             // appropriate locale here
             //
 
@@ -375,4 +382,3 @@ namespace System.Globalization
         }
     }
 }
-
index ef68ce2..c7c129f 100644 (file)
@@ -308,6 +308,6 @@ namespace System.Globalization
             }
         }
 
-        public override int[]? Eras => new int[] { ChineseEra };
+        public override int[] Eras => new int[] { ChineseEra };
     }
 }
index 16201b8..d579dbe 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
index be33668..6a6764a 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
@@ -15,7 +16,7 @@ namespace System.Globalization
     public partial class CompareInfo
     {
         [NonSerialized]
-        private Interop.Globalization.SafeSortHandle _sortHandle;
+        private Interop.Globalization.SafeSortHandle _sortHandle = null!;
 
         [NonSerialized]
         private bool _isAsciiEqualityOrdinal;
@@ -164,8 +165,8 @@ namespace System.Globalization
                 return -1;
             }
 
-            // startIndex is the index into source where we start search backwards from. 
-            // leftStartIndex is the index into source of the start of the string that is 
+            // startIndex is the index into source where we start search backwards from.
+            // leftStartIndex is the index into source of the start of the string that is
             // count characters away from startIndex.
             int leftStartIndex = startIndex - count + 1;
 
@@ -581,7 +582,7 @@ namespace System.Globalization
                     // uppercase both chars - notice that we need just one compare per char
                     if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
                     if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
-                    
+
                     if (charA != charB)
                         return false;
 
@@ -616,7 +617,7 @@ namespace System.Globalization
                 {
                     int charA = *a;
                     int charB = *b;
-                    
+
                     if (charA != charB)
                         return false;
 
@@ -714,7 +715,7 @@ namespace System.Globalization
                     // uppercase both chars - notice that we need just one compare per char
                     if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
                     if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
-                    
+
                     if (charA != charB)
                         return false;
 
@@ -749,7 +750,7 @@ namespace System.Globalization
                 {
                     int charA = *a;
                     int charB = *b;
-                    
+
                     if (charA != charB)
                         return false;
 
@@ -773,10 +774,10 @@ namespace System.Globalization
             {
                 throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
             }
-            
+
             byte [] keyData;
             if (source.Length == 0)
-            { 
+            {
                 keyData = Array.Empty<Byte>();
             }
             else
@@ -797,7 +798,7 @@ namespace System.Globalization
             }
 
             return new SortKey(Name, source, options, keyData);
-        }       
+        }
 
         private static unsafe bool IsSortable(char *text, int length)
         {
@@ -856,7 +857,7 @@ namespace System.Globalization
             {
                 int sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options);
 
-                byte[] borrowedArr = null;
+                byte[]? borrowedArr = null;
                 Span<byte> span = sortKeyLength <= 512 ?
                     stackalloc byte[512] :
                     (borrowedArr = ArrayPool<byte>.Shared.Rent(sortKeyLength));
@@ -912,7 +913,7 @@ namespace System.Globalization
 
             return buffer;
         }
-        
+
         private SortVersion GetSortVersion()
         {
             Debug.Assert(!GlobalizationMode.Invariant);
index 749e2ad..b706ad5 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
@@ -111,7 +112,7 @@ namespace System.Globalization
 
             return FindStringOrdinal(FIND_FROMEND, source, startIndex - count + 1, count, value, value.Length, ignoreCase);
         }
-        
+
         private unsafe int GetHashCodeOfStringCore(ReadOnlySpan<char> source, CompareOptions options)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
@@ -141,7 +142,7 @@ namespace System.Globalization
                 // sort keys, LCMapStringEx treats the output buffer as containing opaque binary data.
                 // See https://docs.microsoft.com/en-us/windows/desktop/api/winnls/nf-winnls-lcmapstringex.
 
-                byte[] borrowedArr = null;
+                byte[]? borrowedArr = null;
                 Span<byte> span = sortKeyLength <= 512 ?
                     stackalloc byte[512] :
                     (borrowedArr = ArrayPool<byte>.Shared.Rent(sortKeyLength));
@@ -177,7 +178,7 @@ namespace System.Globalization
             fixed (char* char1 = &string1)
             fixed (char* char2 = &string2)
             {
-                // Use the OS to compare and then convert the result to expected value by subtracting 2 
+                // Use the OS to compare and then convert the result to expected value by subtracting 2
                 return Interop.Kernel32.CompareStringOrdinal(char1, count1, char2, count2, true) - 2;
             }
         }
@@ -191,7 +192,7 @@ namespace System.Globalization
             Debug.Assert(!GlobalizationMode.Invariant);
             Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
 
-            string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+            string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
 
             fixed (char* pLocaleName = localeName)
             fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
@@ -224,7 +225,7 @@ namespace System.Globalization
             Debug.Assert(!GlobalizationMode.Invariant);
             Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
 
-            string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+            string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
 
             fixed (char* pLocaleName = localeName)
             fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
@@ -263,7 +264,7 @@ namespace System.Globalization
             Debug.Assert(!lpStringSource.IsEmpty);
             Debug.Assert(!lpStringValue.IsEmpty);
 
-            string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+            string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
 
             fixed (char* pLocaleName = localeName)
             fixed (char* pSource = &MemoryMarshal.GetReference(lpStringSource))
@@ -282,7 +283,7 @@ namespace System.Globalization
                                     _sortHandle);
             }
         }
-        
+
         private unsafe int FindString(
             uint dwFindNLSStringFlags,
             string lpStringSource,
@@ -297,7 +298,7 @@ namespace System.Globalization
             Debug.Assert(lpStringSource != null);
             Debug.Assert(lpStringValue != null);
 
-            string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+            string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
 
             fixed (char* pLocaleName = localeName)
             fixed (char* pSource = lpStringSource)
@@ -493,9 +494,9 @@ namespace System.Globalization
                 throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
             }
 
-            byte [] keyData = null;
+            byte [] keyData;
             if (source.Length == 0)
-            { 
+            {
                 keyData = Array.Empty<byte>();
             }
             else
index 97bb90f..f5bba90 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Reflection;
 using System.Runtime.CompilerServices;
@@ -50,10 +51,10 @@ namespace System.Globalization
         private string m_name;  // The name used to construct this CompareInfo. Do not rename (binary serialization)
 
         [NonSerialized]
-        private string _sortName; // The name that defines our behavior
+        private string _sortName = null!; // The name that defines our behavior
 
         [OptionalField(VersionAdded = 3)]
-        private SortVersion m_SortVersion; // Do not rename (binary serialization)
+        private SortVersion? m_SortVersion; // Do not rename (binary serialization)
 
         private int culture; // Do not rename (binary serialization). The fields sole purpose is to support Desktop serialization.
 
@@ -170,7 +171,9 @@ namespace System.Globalization
         [OnDeserializing]
         private void OnDeserializing(StreamingContext ctx)
         {
-            m_name = null;
+            // TODO-NULLABLE: this becomes null for a brief moment before deserialization
+            //                after serialization is finished it is never null
+            m_name = null!;
         }
 
         void IDeserializationCallback.OnDeserialization(object sender)
@@ -216,7 +219,6 @@ namespace System.Globalization
         ///  and the locale's changed behavior, then you'll get changed behavior, which is like
         ///  what happens for a version update)
         /// </summary>
-
         public virtual string Name
         {
             get
@@ -237,12 +239,12 @@ namespace System.Globalization
         /// than string2, and a number greater than 0 if string1 is greater
         /// than string2.
         /// </summary>
-        public virtual int Compare(string string1, string string2)
+        public virtual int Compare(string? string1, string? string2)
         {
             return Compare(string1, string2, CompareOptions.None);
         }
 
-        public virtual int Compare(string string1, string string2, CompareOptions options)
+        public virtual int Compare(string? string1, string? string2, CompareOptions options)
         {
             if (options == CompareOptions.OrdinalIgnoreCase)
             {
@@ -296,7 +298,7 @@ namespace System.Globalization
         // TODO https://github.com/dotnet/coreclr/issues/13827:
         // This method shouldn't be necessary, as we should be able to just use the overload
         // that takes two spans.  But due to this issue, that's adding significant overhead.
-        internal int Compare(ReadOnlySpan<char> string1, string string2, CompareOptions options)
+        internal int Compare(ReadOnlySpan<char> string1, string? string2, CompareOptions options)
         {
             if (options == CompareOptions.OrdinalIgnoreCase)
             {
@@ -368,23 +370,23 @@ namespace System.Globalization
         /// string1 is less than string2, and a number greater than 0 if
         /// string1 is greater than string2.
         /// </summary>
-        public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2)
+        public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2)
         {
             return Compare(string1, offset1, length1, string2, offset2, length2, 0);
         }
 
-        public virtual int Compare(string string1, int offset1, string string2, int offset2, CompareOptions options)
+        public virtual int Compare(string? string1, int offset1, string? string2, int offset2, CompareOptions options)
         {
             return Compare(string1, offset1, string1 == null ? 0 : string1.Length - offset1,
                            string2, offset2, string2 == null ? 0 : string2.Length - offset2, options);
         }
 
-        public virtual int Compare(string string1, int offset1, string string2, int offset2)
+        public virtual int Compare(string? string1, int offset1, string? string2, int offset2)
         {
             return Compare(string1, offset1, string2, offset2, 0);
         }
 
-        public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
+        public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2, CompareOptions options)
         {
             if (options == CompareOptions.OrdinalIgnoreCase)
             {
@@ -499,7 +501,7 @@ namespace System.Globalization
 
             while (length != 0 && charA <= maxChar && charB <= maxChar)
             {
-                // Ordinal equals or lowercase equals if the result ends up in the a-z range 
+                // Ordinal equals or lowercase equals if the result ends up in the a-z range
                 if (charA == charB ||
                     ((charA | 0x20) == (charB | 0x20) &&
                         (uint)((charA | 0x20) - 'a') <= (uint)('z' - 'a')))
@@ -659,7 +661,7 @@ namespace System.Globalization
                 IntPtr byteOffset = IntPtr.Zero;
                 while (length != 0)
                 {
-                    // Ordinal equals or lowercase equals if the result ends up in the a-z range 
+                    // Ordinal equals or lowercase equals if the result ends up in the a-z range
                     uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset);
                     uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset);
 
@@ -1339,7 +1341,7 @@ namespace System.Globalization
             return CreateSortKey(source, CompareOptions.None);
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             return value is CompareInfo otherCompareInfo
                 && Name == otherCompareInfo.Name;
index 57226ff..f1a2669 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -17,8 +18,7 @@ namespace System.Globalization
         const int ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY = 100; // max size of keyword or value
         const int ICU_ULOC_FULLNAME_CAPACITY = 157;           // max size of locale name
         const string ICU_COLLATION_KEYWORD = "@collation=";
-        
-        
+
         /// <summary>
         /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
         /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
@@ -58,6 +58,7 @@ namespace System.Globalization
             }
 
             // Replace the ICU collation keyword with an _
+            Debug.Assert(_sWindowsName != null);
             index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
             if (index >= 0)
             {
@@ -76,9 +77,9 @@ namespace System.Globalization
             }
 
             _bNeutral = TwoLetterISOCountryName.Length == 0;
-            
-            _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;   
-            
+
+            _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
+
             // Remove the sort from sName unless custom culture
             if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
             {
@@ -87,7 +88,7 @@ namespace System.Globalization
             return true;
         }
 
-        internal static unsafe bool GetLocaleName(string localeName, out string windowsName)
+        internal static unsafe bool GetLocaleName(string localeName, out string? windowsName)
         {
             // Get the locale name from ICU
             char* buffer = stackalloc char[ICU_ULOC_FULLNAME_CAPACITY];
@@ -102,7 +103,7 @@ namespace System.Globalization
             return true;
         }
 
-        internal static unsafe bool GetDefaultLocaleName(out string windowsName)
+        internal static unsafe bool GetDefaultLocaleName(out string? windowsName)
         {
             // Get the default (system) locale name from ICU
             char* buffer = stackalloc char[ICU_ULOC_FULLNAME_CAPACITY];
@@ -116,11 +117,11 @@ namespace System.Globalization
             windowsName = new string(buffer); // the name passed to subsequent ICU calls
             return true;
         }
-        
+
         private string GetLocaleInfo(LocaleStringData type)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
-            
+
             Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
             return GetLocaleInfo(_sWindowsName, type);
         }
@@ -163,7 +164,7 @@ namespace System.Globalization
                     // returning 0 will cause the first supported calendar to be returned, which is the preferred calendar
                     return 0;
             }
-            
+
 
             int value = 0;
             bool result = Interop.Globalization.GetLocaleInfoInt(_sWindowsName, (uint)type, ref value);
@@ -230,7 +231,7 @@ namespace System.Globalization
             return new string[] { format };
         }
 
-        private static CultureData GetCultureDataFromRegionName(string regionName)
+        private static CultureData? GetCultureDataFromRegionName(string? regionName)
         {
             // no support to lookup by region name, other than the hard-coded list in CultureData
             return null;
@@ -241,7 +242,7 @@ namespace System.Globalization
             return new CultureInfo(cultureName)._cultureData.GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName);
         }
 
-        private static string GetRegionDisplayName(string isoCountryCode)
+        private static string? GetRegionDisplayName(string? isoCountryCode)
         {
             // use the fallback which is to return NativeName
             return null;
@@ -293,8 +294,8 @@ namespace System.Globalization
 
             return result.Slice(0, resultPos).ToString();
         }
-        
-        private static string LCIDToLocaleName(int culture)
+
+        private static string? LCIDToLocaleName(int culture)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
 
@@ -304,85 +305,84 @@ namespace System.Globalization
         private static int LocaleNameToLCID(string cultureName)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
-            
+
             int lcid = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.Lcid);
-            return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid; 
+            return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid;
         }
-        
+
         private static int GetAnsiCodePage(string cultureName)
         {
             int ansiCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.AnsiCodePage);
-            return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage; 
+            return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage;
         }
 
         private static int GetOemCodePage(string cultureName)
         {
             int oemCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.OemCodePage);
-            return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage; 
+            return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage;
         }
 
         private static int GetMacCodePage(string cultureName)
         {
             int macCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.MacCodePage);
-            return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage; 
+            return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage;
         }
 
         private static int GetEbcdicCodePage(string cultureName)
         {
             int ebcdicCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.EbcdicCodePage);
-            return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage; 
+            return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage;
         }
 
         private static int GetGeoId(string cultureName)
         {
             int geoId = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.GeoId);
-            return geoId == -1 ? CultureData.Invariant.GeoId : geoId; 
+            return geoId == -1 ? CultureData.Invariant.GeoId : geoId;
         }
-        
+
         private static int GetDigitSubstitution(string cultureName)
         {
             int digitSubstitution = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.DigitSubstitution);
-            return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution; 
+            return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution;
         }
 
         private static string GetThreeLetterWindowsLanguageName(string cultureName)
         {
-            string langName = LocaleData.GetThreeLetterWindowsLanguageName(cultureName);
-            return langName == null ? "ZZZ" /* default lang name */ : langName; 
+            return LocaleData.GetThreeLetterWindowsLanguageName(cultureName) ?? "ZZZ" /* default lang name */;
         }
 
         private static CultureInfo[] EnumCultures(CultureTypes types)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
-            
+
             if ((types & (CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) == 0)
             {
                 return Array.Empty<CultureInfo>();
             }
-            
+
             int bufferLength = Interop.Globalization.GetLocales(null, 0);
             if (bufferLength <= 0)
             {
                 return Array.Empty<CultureInfo>();
             }
-            
+
             char [] chars = new char[bufferLength];
-            
+
             bufferLength = Interop.Globalization.GetLocales(chars, bufferLength);
             if (bufferLength <= 0)
             {
                 return Array.Empty<CultureInfo>();
             }
-            
-            bool enumNeutrals   = (types & CultureTypes.NeutralCultures) != 0; 
-            bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0; 
-            
+
+            bool enumNeutrals   = (types & CultureTypes.NeutralCultures) != 0;
+            bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0;
+
             List<CultureInfo> list = new List<CultureInfo>();
-            if (enumNeutrals) 
+            if (enumNeutrals)
             {
                 list.Add(CultureInfo.InvariantCulture);
             }
-            
+
             int index = 0;
             while (index < bufferLength)
             {
@@ -395,22 +395,22 @@ namespace System.Globalization
                         list.Add(ci);
                     }
                 }
-                
+
                 index += length;
             }
-            
+
             return list.ToArray();
         }
-        
+
         private static string GetConsoleFallbackName(string cultureName)
         {
             return LocaleData.GetConsoleUICulture(cultureName);
         }
-        
+
         internal bool IsFramework => false;
-        
+
         internal bool IsWin32Installed => false;
-        
+
         internal bool IsReplacementCulture => false;
     }
 }
index 151f771..f27b97e 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
@@ -153,7 +154,7 @@ namespace System.Globalization
 
         // Wrappers around the GetLocaleInfoEx APIs which handle marshalling the returned
         // data as either and Int or string.
-        internal static unsafe string GetLocaleInfoEx(string localeName, uint field)
+        internal static unsafe string? GetLocaleInfoEx(string localeName, uint field)
         {
             // REVIEW: Determine the maximum size for the buffer
             const int BUFFER_SIZE = 530;
@@ -211,16 +212,18 @@ namespace System.Globalization
             // Ask OS for data, note that we presume it returns success, so we have to know that
             // sWindowsName is valid before calling.
             Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
-            return  GetLocaleInfoExInt(_sWindowsName, lctype);
+            return GetLocaleInfoExInt(_sWindowsName, lctype);
         }
 
         private int[] GetLocaleInfo(LocaleGroupingData type)
         {
+            Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
             return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, UseUserOverride));
         }
 
-        private string GetTimeFormatString()
+        private string? GetTimeFormatString()
         {
+            Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
             return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, Interop.Kernel32.LOCALE_STIMEFORMAT, UseUserOverride));
         }
 
@@ -234,27 +237,27 @@ namespace System.Globalization
             return ConvertFirstDayOfWeekMonToSun(result);
         }
 
-        private string[] GetTimeFormats()
+        private string[]? GetTimeFormats()
         {
             // Note that this gets overrides for us all the time
             Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already");
-            string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
+            string[]? result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
 
             return result;
         }
 
-        private string[] GetShortTimeFormats()
+        private string[]? GetShortTimeFormats()
         {
             // Note that this gets overrides for us all the time
             Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
-            string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride));
+            string[]? result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride));
 
             return result;
         }
 
         // Enumerate all system cultures and then try to find out which culture has
         // region name match the requested region name
-        private static CultureData GetCultureDataFromRegionName(string regionName)
+        private static CultureData? GetCultureDataFromRegionName(string regionName)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
             Debug.Assert(regionName != null);
@@ -284,7 +287,7 @@ namespace System.Globalization
 #else
             // Usually the UI culture shouldn't be different than what we got from WinRT except
             // if DefaultThreadCurrentUICulture was set
-            CultureInfo ci;
+            CultureInfo? ci;
 
             if (CultureInfo.DefaultThreadCurrentUICulture != null &&
                 ((ci = GetUserDefaultCulture()) != null) &&
@@ -337,14 +340,8 @@ namespace System.Globalization
             }
 
             // Ask OS for data
-            string result = GetLocaleInfoEx(localeName, lctype);
-            if (result == null)
-            {
-                // Failed, just use empty string
-                result = string.Empty;
-            }
-
-            return result;
+            // Failed? Just use empty string
+            return GetLocaleInfoEx(localeName, lctype) ?? string.Empty;
         }
 
         /// <summary>
@@ -360,7 +357,7 @@ namespace System.Globalization
         ///
         /// We don't build the stringbuilder unless we find something to change
         /// </summary>
-        internal static string ReescapeWin32String(string str)
+        internal static string? ReescapeWin32String(string? str)
         {
             // If we don't have data, then don't try anything
             if (str == null)
@@ -368,7 +365,7 @@ namespace System.Globalization
                 return null;
             }
 
-            StringBuilder result = null;
+            StringBuilder? result = null;
 
             bool inQuote = false;
             for (int i = 0; i < str.Length; i++)
@@ -428,13 +425,14 @@ namespace System.Globalization
             return result.ToString();
         }
 
-        internal static string[] ReescapeWin32Strings(string[] array)
+        internal static string[]? ReescapeWin32Strings(string[]? array)
         {
             if (array != null)
             {
                 for (int i = 0; i < array.Length; i++)
                 {
-                    array[i] = ReescapeWin32String(array[i]);
+                    // only returns null when null is passed
+                    array[i] = ReescapeWin32String(array[i])!;
                 }
             }
 
@@ -503,7 +501,7 @@ namespace System.Globalization
         private struct EnumLocaleData
         {
             public string regionName;
-            public string cultureName;
+            public string? cultureName;
         }
 
         // EnumSystemLocaleEx callback.
@@ -514,7 +512,7 @@ namespace System.Globalization
             try
             {
                 string cultureName = new string(lpLocaleString);
-                string regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME);
+                string? regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME);
                 if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase))
                 {
                     context.cultureName = cultureName;
@@ -567,7 +565,7 @@ namespace System.Globalization
             }
         }
 
-        private static unsafe string[] nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride)
+        private static unsafe string[]? nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride)
         {
             EnumData data = new EnumData();
             data.strings = new List<string>();
@@ -614,7 +612,7 @@ namespace System.Globalization
             return Interop.Kernel32.LocaleNameToLCID(cultureName, Interop.Kernel32.LOCALE_ALLOW_NEUTRAL_NAMES);
         }
 
-        private static unsafe string LCIDToLocaleName(int culture)
+        private static unsafe string? LCIDToLocaleName(int culture)
         {
             Debug.Assert(!GlobalizationMode.Invariant);
 
index 1280119..193d3d9 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Text;
@@ -55,87 +56,87 @@ namespace System.Globalization
         private const int undef = -1;
 
         // Override flag
-        private string _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
-        private string _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
+        private string _sRealName = null!; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
+        private string? _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
 
         // Identity
-        private string _sName; // locale name (ie: en-us, NO sort info, but could be neutral)
-        private string _sParent; // Parent name (which may be a custom locale/culture)
-        private string _sLocalizedDisplayName; // Localized pretty name for this locale
-        private string _sEnglishDisplayName; // English pretty name for this locale
-        private string _sNativeDisplayName; // Native pretty name for this locale
-        private string _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
+        private string? _sName; // locale name (ie: en-us, NO sort info, but could be neutral)
+        private string? _sParent; // Parent name (which may be a custom locale/culture)
+        private string? _sLocalizedDisplayName; // Localized pretty name for this locale
+        private string? _sEnglishDisplayName; // English pretty name for this locale
+        private string? _sNativeDisplayName; // Native pretty name for this locale
+        private string? _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
 
         // Language
-        private string _sISO639Language; // ISO 639 Language Name
-        private string _sISO639Language2; // ISO 639 Language Name
-        private string _sLocalizedLanguage; // Localized name for this language
-        private string _sEnglishLanguage; // English name for this language
-        private string _sNativeLanguage; // Native name of this language
-        private string _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
-        private string _sConsoleFallbackName; // The culture name for the console fallback UI culture
+        private string? _sISO639Language; // ISO 639 Language Name
+        private string? _sISO639Language2; // ISO 639 Language Name
+        private string? _sLocalizedLanguage; // Localized name for this language
+        private string? _sEnglishLanguage; // English name for this language
+        private string? _sNativeLanguage; // Native name of this language
+        private string? _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
+        private string? _sConsoleFallbackName; // The culture name for the console fallback UI culture
         private int    _iInputLanguageHandle=undef;// input language handle
 
         // Region
-        private string _sRegionName; // (RegionInfo)
-        private string _sLocalizedCountry; // localized country name
-        private string _sEnglishCountry; // english country name (RegionInfo)
-        private string _sNativeCountry; // native country name
-        private string _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
-        private string _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
+        private string? _sRegionName; // (RegionInfo)
+        private string? _sLocalizedCountry; // localized country name
+        private string? _sEnglishCountry; // english country name (RegionInfo)
+        private string? _sNativeCountry; // native country name
+        private string? _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
+        private string? _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
         private int    _iGeoId = undef; // GeoId
 
         // Numbers
-        private string _sPositiveSign; // (user can override) positive sign
-        private string _sNegativeSign; // (user can override) negative sign
+        private string? _sPositiveSign; // (user can override) positive sign
+        private string? _sNegativeSign; // (user can override) negative sign
         // (nfi populates these 5, don't have to be = undef)
         private int _iDigits; // (user can override) number of fractional digits
         private int _iNegativeNumber; // (user can override) negative number format
-        private int[] _waGrouping; // (user can override) grouping of digits
-        private string _sDecimalSeparator; // (user can override) decimal separator
-        private string _sThousandSeparator; // (user can override) thousands separator
-        private string _sNaN; // Not a Number
-        private string _sPositiveInfinity; // + Infinity
-        private string _sNegativeInfinity; // - Infinity
+        private int[]? _waGrouping; // (user can override) grouping of digits
+        private string? _sDecimalSeparator; // (user can override) decimal separator
+        private string? _sThousandSeparator; // (user can override) thousands separator
+        private string? _sNaN; // Not a Number
+        private string? _sPositiveInfinity; // + Infinity
+        private string? _sNegativeInfinity; // - Infinity
 
         // Percent
         private int _iNegativePercent = undef; // Negative Percent (0-3)
         private int _iPositivePercent = undef; // Positive Percent (0-11)
-        private string _sPercent; // Percent (%) symbol
-        private string _sPerMille; // PerMille symbol
+        private string? _sPercent; // Percent (%) symbol
+        private string? _sPerMille; // PerMille symbol
 
         // Currency
-        private string _sCurrency; // (user can override) local monetary symbol
-        private string _sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
-        private string _sEnglishCurrency; // English name for this currency
-        private string _sNativeCurrency; // Native name for this currency
+        private string? _sCurrency; // (user can override) local monetary symbol
+        private string? _sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
+        private string? _sEnglishCurrency; // English name for this currency
+        private string? _sNativeCurrency; // Native name for this currency
         // (nfi populates these 4, don't have to be = undef)
         private int _iCurrencyDigits; // (user can override) # local monetary fractional digits
         private int _iCurrency; // (user can override) positive currency format
         private int _iNegativeCurrency; // (user can override) negative currency format
-        private int[] _waMonetaryGrouping; // (user can override) monetary grouping of digits
-        private string _sMonetaryDecimal; // (user can override) monetary decimal separator
-        private string _sMonetaryThousand; // (user can override) monetary thousands separator
+        private int[]? _waMonetaryGrouping; // (user can override) monetary grouping of digits
+        private string? _sMonetaryDecimal; // (user can override) monetary decimal separator
+        private string? _sMonetaryThousand; // (user can override) monetary thousands separator
 
         // Misc
         private int _iMeasure = undef; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
-        private string _sListSeparator; // (user can override) list separator
+        private string? _sListSeparator; // (user can override) list separator
 
         // Time
-        private string _sAM1159; // (user can override) AM designator
-        private string _sPM2359; // (user can override) PM designator
-        private string _sTimeSeparator;
-        private volatile string[] _saLongTimes; // (user can override) time format
-        private volatile string[] _saShortTimes; // short time format
-        private volatile string[] _saDurationFormats; // time duration format
+        private string? _sAM1159; // (user can override) AM designator
+        private string? _sPM2359; // (user can override) PM designator
+        private string? _sTimeSeparator;
+        private volatile string[]? _saLongTimes; // (user can override) time format
+        private volatile string[]? _saShortTimes; // short time format
+        private volatile string[]? _saDurationFormats; // time duration format
 
         // Calendar specific data
         private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really)
         private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really)
-        private volatile CalendarId[] _waCalendars; // all available calendar type(s).  The first one is the default calendar
+        private volatile CalendarId[]? _waCalendars; // all available calendar type(s).  The first one is the default calendar
 
         // Store for specific data about each calendar
-        private CalendarData[] _calendars; // Store for specific calendar data
+        private CalendarData?[]? _calendars; // Store for specific calendar data
 
         // Text information
         private int _iReadingLayout = undef; // Reading layout data
@@ -301,15 +302,15 @@ namespace System.Globalization
                     s_regionNames = regionNames;
                 }
 
-                return s_regionNames;
+                return s_regionNames!;
             }
         }
 
         // Cache of regions we've already looked up
-        private static volatile StringCultureDataDictionary s_cachedRegions;
-        private static volatile StringStringDictionary s_regionNames;
+        private static volatile StringCultureDataDictionary? s_cachedRegions;
+        private static volatile StringStringDictionary? s_regionNames;
 
-        internal static CultureData GetCultureDataForRegion(string cultureName, bool useUserOverride)
+        internal static CultureData? GetCultureDataForRegion(string? cultureName, bool useUserOverride)
         {
             // First do a shortcut for Invariant
             if (string.IsNullOrEmpty(cultureName))
@@ -318,7 +319,7 @@ namespace System.Globalization
             }
 
             // First check if GetCultureData() can find it (ie: its a real culture)
-            CultureData retVal = GetCultureData(cultureName, useUserOverride);
+            CultureData? retVal = GetCultureData(cultureName, useUserOverride);
             if (retVal != null && !retVal.IsNeutralCulture)
             {
                 return retVal;
@@ -328,11 +329,12 @@ namespace System.Globalization
             // (Remember this isn't a core clr path where that's not supported)
 
             // If it was neutral remember that so that RegionInfo() can throw the right exception
-            CultureData neutral = retVal;
+            CultureData? neutral = retVal;
 
             // Try the hash table next
             string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
-            StringCultureDataDictionary tempHashTable = s_cachedRegions;
+            StringCultureDataDictionary? tempHashTable = s_cachedRegions;
+
             if (tempHashTable == null)
             {
                 // No table yet, make a new one
@@ -562,13 +564,13 @@ namespace System.Globalization
                 return s_Invariant;
             }
         }
-        private volatile static CultureData s_Invariant;
+        private volatile static CultureData? s_Invariant;
 
         // Cache of cultures we've already looked up
-        private static volatile StringCultureDataDictionary s_cachedCultures;
+        private static volatile StringCultureDataDictionary? s_cachedCultures;
         private static readonly object s_lock = new object();
 
-        internal static CultureData GetCultureData(string cultureName, bool useUserOverride)
+        internal static CultureData? GetCultureData(string? cultureName, bool useUserOverride)
         {
             // First do a shortcut for Invariant
             if (string.IsNullOrEmpty(cultureName))
@@ -578,7 +580,7 @@ namespace System.Globalization
 
             // Try the hash table first
             string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
-            StringCultureDataDictionary tempHashTable = s_cachedCultures;
+            StringCultureDataDictionary? tempHashTable = s_cachedCultures;
             if (tempHashTable == null)
             {
                 // No table yet, make a new one
@@ -600,7 +602,7 @@ namespace System.Globalization
             }
 
             // Not found in the hash table, need to see if we can build one that works for us
-            CultureData culture = CreateCultureData(cultureName, useUserOverride);
+            CultureData? culture = CreateCultureData(cultureName, useUserOverride);
             if (culture == null)
             {
                 return null;
@@ -677,7 +679,7 @@ namespace System.Globalization
             return name;
         }
 
-        private static CultureData CreateCultureData(string cultureName, bool useUserOverride)
+        private static CultureData? CreateCultureData(string cultureName, bool useUserOverride)
         {
             if (GlobalizationMode.Invariant)
             {
@@ -711,7 +713,7 @@ namespace System.Globalization
         private bool InitCompatibilityCultureData()
         {
             // for compatibility handle the deprecated ids: zh-chs, zh-cht
-            string cultureName = _sRealName;
+            string cultureName = _sRealName!;
 
             string fallbackCultureName;
             string realCultureName;
@@ -745,8 +747,8 @@ namespace System.Globalization
         /// We'd rather people use the named version since this doesn't allow custom locales
         internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
         {
-            string localeName = null;
-            CultureData retVal = null;
+            string? localeName = null;
+            CultureData? retVal = null;
 
             if (culture == CultureInfo.LOCALE_INVARIANT)
             {
@@ -794,9 +796,10 @@ namespace System.Globalization
                 {
                     case "zh-CHS":
                     case "zh-CHT":
-                        return _sName;
+                        // TODO-NULLABLE: dotnet/roslyn#34273
+                        return _sName!;
                 }
-                return _sRealName;
+                return _sRealName!;
             }
         }
 
@@ -818,7 +821,7 @@ namespace System.Globalization
                 if (_sParent == null)
                 {
                     // Ask using the real name, so that we get parents of neutrals
-                    _sParent = GetLocaleInfo(_sRealName, LocaleStringData.ParentName);
+                    _sParent = GetLocaleInfo(_sRealName!, LocaleStringData.ParentName);
                 }
                 return _sParent;
             }
@@ -935,7 +938,7 @@ namespace System.Globalization
                             {
                                 // "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
                                 _sEnglishDisplayName = string.Concat(
-                                    EnglishLanguageName.AsSpan(0, _sEnglishLanguage.Length - 1),
+                                    EnglishLanguageName.AsSpan(0, _sEnglishLanguage!.Length - 1),
                                     ", ",
                                     EnglishCountryName,
                                     ")");
@@ -1044,7 +1047,7 @@ namespace System.Globalization
             {
                 if (_sAbbrevLang == null)
                 {
-                    _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName);
+                    _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName!);
                 }
                 return _sAbbrevLang;
             }
@@ -1066,7 +1069,7 @@ namespace System.Globalization
 
                     if (CultureInfo.DefaultThreadCurrentUICulture != null &&
                         ((ci = GetUserDefaultCulture()) != null) &&
-                        !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
+                        !CultureInfo.DefaultThreadCurrentUICulture!.Name.Equals(ci.Name))
                     {
                         _sLocalizedLanguage = NativeLanguageName;
                     }
@@ -1131,7 +1134,7 @@ namespace System.Globalization
             {
                 if (_iGeoId == undef)
                 {
-                    _iGeoId = GetGeoId(_sRealName);
+                    _iGeoId = GetGeoId(_sRealName!);
                 }
                 return _iGeoId;
             }
@@ -1253,7 +1256,7 @@ namespace System.Globalization
             {
                 if (_sConsoleFallbackName == null)
                 {
-                    _sConsoleFallbackName = GetConsoleFallbackName(_sRealName);
+                    _sConsoleFallbackName = GetConsoleFallbackName(_sRealName!);
                 }
                 return _sConsoleFallbackName;
             }
@@ -1528,10 +1531,10 @@ namespace System.Globalization
                 {
                     Debug.Assert(!GlobalizationMode.Invariant);
 
-                    string[] longTimes = GetTimeFormats();
+                    string[]? longTimes = GetTimeFormats();
                     if (longTimes == null || longTimes.Length == 0)
                     {
-                        _saLongTimes = Invariant._saLongTimes;
+                        _saLongTimes = Invariant._saLongTimes!;
                     }
                     else
                     {
@@ -1555,8 +1558,7 @@ namespace System.Globalization
                     Debug.Assert(!GlobalizationMode.Invariant);
 
                     // Try to get the short times from the OS/culture.dll
-                    string[] shortTimes = null;
-                    shortTimes = GetShortTimeFormats();
+                    string[]? shortTimes = GetShortTimeFormats();
 
                     if (shortTimes == null || shortTimes.Length == 0)
                     {
@@ -1830,7 +1832,7 @@ namespace System.Globalization
                     if (count == 0)
                     {
                         // Failed for some reason, just grab Gregorian from Invariant
-                        _waCalendars = Invariant._waCalendars;
+                        _waCalendars = Invariant._waCalendars!;
                     }
                     else
                     {
@@ -1912,7 +1914,7 @@ namespace System.Globalization
             // we need the following local variable to avoid returning null
             // when another thread creates a new array of CalendarData (above)
             // right after we insert the newly created CalendarData (below)
-            CalendarData calendarData = _calendars[calendarIndex];
+            CalendarData? calendarData = _calendars[calendarIndex];
             // Make sure that calendar has data
             if (calendarData == null)
             {
@@ -2002,7 +2004,7 @@ namespace System.Globalization
             {
                 if (_iDefaultAnsiCodePage == undef)
                 {
-                    _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName);
+                    _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName!);
                 }
                 return _iDefaultAnsiCodePage;
             }
@@ -2017,7 +2019,7 @@ namespace System.Globalization
             {
                 if (_iDefaultOemCodePage == undef)
                 {
-                    _iDefaultOemCodePage = GetOemCodePage(_sRealName);
+                    _iDefaultOemCodePage = GetOemCodePage(_sRealName!);
                 }
                 return _iDefaultOemCodePage;
             }
@@ -2032,7 +2034,7 @@ namespace System.Globalization
             {
                 if (_iDefaultMacCodePage == undef)
                 {
-                    _iDefaultMacCodePage = GetMacCodePage(_sRealName);
+                    _iDefaultMacCodePage = GetMacCodePage(_sRealName!);
                 }
                 return _iDefaultMacCodePage;
             }
@@ -2047,7 +2049,7 @@ namespace System.Globalization
             {
                 if (_iDefaultEbcdicCodePage == undef)
                 {
-                    _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName);
+                    _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName!);
                 }
                 return _iDefaultEbcdicCodePage;
             }
@@ -2136,7 +2138,7 @@ namespace System.Globalization
             {
                 if (_sTimeSeparator == null)
                 {
-                    string longTimeFormat = GetTimeFormatString();
+                    string? longTimeFormat = GetTimeFormatString();
                     if (string.IsNullOrEmpty(longTimeFormat))
                     {
                         longTimeFormat = LongTimes[0];
@@ -2190,7 +2192,7 @@ namespace System.Globalization
             Debug.Assert(str != null);
             Debug.Assert(start >= 0);
             Debug.Assert(end >= 0);
-            StringBuilder result = null;
+            StringBuilder? result = null;
 
             for (int i = start; i < str.Length && i <= end; i++)
             {
@@ -2328,17 +2330,17 @@ namespace System.Globalization
         {
             if (GlobalizationMode.Invariant || IsInvariantCulture)
             {
-                nfi._positiveSign = _sPositiveSign;
-                nfi._negativeSign = _sNegativeSign;
+                nfi._positiveSign = _sPositiveSign!;
+                nfi._negativeSign = _sNegativeSign!;
 
-                nfi._numberGroupSeparator = _sThousandSeparator;
-                nfi._numberDecimalSeparator = _sDecimalSeparator;
+                nfi._numberGroupSeparator = _sThousandSeparator!;
+                nfi._numberDecimalSeparator = _sDecimalSeparator!;
                 nfi._numberDecimalDigits = _iDigits;
                 nfi._numberNegativePattern = _iNegativeNumber;
 
-                nfi._currencySymbol = _sCurrency;
-                nfi._currencyGroupSeparator = _sMonetaryThousand;
-                nfi._currencyDecimalSeparator = _sMonetaryDecimal;
+                nfi._currencySymbol = _sCurrency!;
+                nfi._currencyGroupSeparator = _sMonetaryThousand!;
+                nfi._currencyDecimalSeparator = _sMonetaryDecimal!;
                 nfi._currencyDecimalDigits = _iCurrencyDigits;
                 nfi._currencyNegativePattern = _iNegativeCurrency;
                 nfi._currencyPositivePattern = _iCurrency;
@@ -2371,6 +2373,7 @@ namespace System.Globalization
                     nfi._nativeDigits[i] = char.ToString(digits[i]);
                 }
 
+                Debug.Assert(_sRealName != null);
                 nfi._digitSubstitution = GetDigitSubstitution(_sRealName);
             }
 
index d7adc02..0973ee0 100644 (file)
@@ -3,6 +3,8 @@
 // See the LICENSE file in the project root for more information.
 
 #nullable enable
+using System.Diagnostics;
+
 namespace System.Globalization
 {
     public partial class CultureInfo : IFormatProvider
@@ -13,9 +15,10 @@ namespace System.Globalization
                 return CultureInfo.InvariantCulture;
 
             CultureInfo cultureInfo;
-            string localeName;
+            string? localeName;
             if (CultureData.GetDefaultLocaleName(out localeName))
             {
+                Debug.Assert(localeName != null);
                 cultureInfo = GetCultureByName(localeName);
             }
             else
index 72db2db..09041e9 100644 (file)
@@ -25,7 +25,7 @@ namespace System.Globalization
             if (GlobalizationMode.Invariant)
                 return CultureInfo.InvariantCulture;
 
-            string strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
+            string? strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
             if (strDefault == null)
             {
                 strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_SYSTEM_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
index c02a2ed..643327c 100644 (file)
@@ -175,13 +175,14 @@ namespace System.Globalization
             }
 
             // Get our data providing record
-            _cultureData = CultureData.GetCultureData(name, useUserOverride);
+            CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride);
 
-            if (_cultureData == null)
+            if (cultureData == null)
             {
                 throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported);
             }
 
+            _cultureData = cultureData;
             _name = _cultureData.CultureName;
             _isInherited = GetType() != typeof(CultureInfo);
         }
@@ -253,12 +254,14 @@ namespace System.Globalization
                 throw new ArgumentNullException(nameof(cultureName), SR.ArgumentNull_String);
             }
 
-            _cultureData = CultureData.GetCultureData(cultureName, false);
-            if (_cultureData == null)
+            CultureData? cultureData = CultureData.GetCultureData(cultureName, false);
+            if (cultureData == null)
             {
                 throw new CultureNotFoundException(nameof(cultureName), cultureName, SR.Argument_CultureNotSupported);
             }
 
+            _cultureData = cultureData;
+
             _name = _cultureData.CultureName;
 
             CultureInfo altCulture = GetCultureInfo(textAndCompareCultureName);
index 007aff7..cb61d50 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Runtime.Serialization;
 
 namespace System.Globalization
@@ -10,7 +11,7 @@ namespace System.Globalization
     [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
     public class CultureNotFoundException : ArgumentException
     {
-        private string _invalidCultureName; // unrecognized culture name
+        private string? _invalidCultureName; // unrecognized culture name
         private int? _invalidCultureId;     // unrecognized culture Lcid
 
         public CultureNotFoundException()
@@ -18,40 +19,40 @@ namespace System.Globalization
         {
         }
 
-        public CultureNotFoundException(string message)
+        public CultureNotFoundException(string? message)
             : base(message)
         {
         }
 
-        public CultureNotFoundException(string paramName, string message)
+        public CultureNotFoundException(string? paramName, string? message)
             : base(message, paramName)
         {
         }
 
-        public CultureNotFoundException(string message, Exception innerException)
+        public CultureNotFoundException(string? message, Exception? innerException)
             : base(message, innerException)
         {
         }
 
-        public CultureNotFoundException(string paramName, string invalidCultureName, string message)
+        public CultureNotFoundException(string? paramName, string? invalidCultureName, string? message)
             : base(message, paramName)
         {
             _invalidCultureName = invalidCultureName;
         }
 
-        public CultureNotFoundException(string message, string invalidCultureName, Exception innerException)
+        public CultureNotFoundException(string? message, string? invalidCultureName, Exception? innerException)
             : base(message, innerException)
         {
             _invalidCultureName = invalidCultureName;
         }
 
-        public CultureNotFoundException(string message, int invalidCultureId, Exception innerException)
+        public CultureNotFoundException(string? message, int invalidCultureId, Exception? innerException)
             : base(message, innerException)
         {
             _invalidCultureId = invalidCultureId;
         }
 
-        public CultureNotFoundException(string paramName, int invalidCultureId, string message)
+        public CultureNotFoundException(string? paramName, int invalidCultureId, string? message)
             : base(message, paramName)
         {
             _invalidCultureId = invalidCultureId;
@@ -76,7 +77,7 @@ namespace System.Globalization
             get { return _invalidCultureId; }
         }
 
-        public virtual string InvalidCultureName
+        public virtual string? InvalidCultureName
         {
             get { return _invalidCultureName; }
         }
@@ -89,7 +90,7 @@ namespace System.Globalization
             }
         }
 
-        private string FormatedInvalidCultureId
+        private string? FormattedInvalidCultureId
         {
             get
             {
@@ -106,7 +107,7 @@ namespace System.Globalization
                 string s = base.Message;
                 if (_invalidCultureId != null || _invalidCultureName != null)
                 {
-                    string valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormatedInvalidCultureId);
+                    string valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormattedInvalidCultureId);
                     if (s == null)
                     {
                         return valueMessage;
index 310771d..4ff0554 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
@@ -57,29 +58,29 @@ namespace System.Globalization
         private CultureData _cultureData;
 
         // The culture name used to create this DTFI.
-        private string _name = null;
+        private string? _name = null;
 
         // The language name of the culture used to create this DTFI.
-        private string _langName = null;
+        private string? _langName = null;
 
         // CompareInfo usually used by the parser.
-        private CompareInfo _compareInfo = null;
+        private CompareInfo? _compareInfo = null;
 
         // Culture matches current DTFI. mainly used for string comparisons during parsing.
-        private CultureInfo _cultureInfo = null;
+        private CultureInfo? _cultureInfo = null;
 
-        private string amDesignator = null;
-        private string pmDesignator = null;
+        private string? amDesignator = null;
+        private string? pmDesignator = null;
 
-        private string dateSeparator = null;            // derived from short date (whidbey expects, arrowhead doesn't)
+        private string? dateSeparator = null;            // derived from short date (whidbey expects, arrowhead doesn't)
 
-        private string generalShortTimePattern = null;     // short date + short time (whidbey expects, arrowhead doesn't)
+        private string? generalShortTimePattern = null;     // short date + short time (whidbey expects, arrowhead doesn't)
 
-        private string generalLongTimePattern = null;     // short date + long time (whidbey expects, arrowhead doesn't)
+        private string? generalLongTimePattern = null;     // short date + long time (whidbey expects, arrowhead doesn't)
 
-        private string timeSeparator = null;            // derived from long time (whidbey expects, arrowhead doesn't)
-        private string monthDayPattern = null;
-        private string dateTimeOffsetPattern = null;
+        private string? timeSeparator = null;            // derived from long time (whidbey expects, arrowhead doesn't)
+        private string? monthDayPattern = null;
+        private string? dateTimeOffsetPattern = null;
 
         private const string rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
 
@@ -87,31 +88,31 @@ namespace System.Globalization
         private const string sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
         private const string universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
 
-        private Calendar calendar = null;
+        private Calendar calendar = null!;
 
         private int firstDayOfWeek = -1;
         private int calendarWeekRule = -1;
 
-        private string fullDateTimePattern = null;        // long date + long time (whidbey expects, arrowhead doesn't)
+        private string? fullDateTimePattern = null;        // long date + long time (whidbey expects, arrowhead doesn't)
 
-        private string[] abbreviatedDayNames = null;
+        private string[]? abbreviatedDayNames = null;
 
-        private string[] m_superShortDayNames = null;
+        private string[]? m_superShortDayNames = null;
 
-        private string[] dayNames = null;
-        private string[] abbreviatedMonthNames = null;
-        private string[] monthNames = null;
+        private string[]? dayNames = null;
+        private string[]? abbreviatedMonthNames = null;
+        private string[]? monthNames = null;
 
         // Cache the genitive month names that we retrieve from the data table.
 
-        private string[] genitiveMonthNames = null;
+        private string[]? genitiveMonthNames = null;
 
         // Cache the abbreviated genitive month names that we retrieve from the data table.
 
-        private string[] m_genitiveAbbreviatedMonthNames = null;
+        private string[]? m_genitiveAbbreviatedMonthNames = null;
 
         // Cache the month names of a leap year that we retrieve from the data table.
-        private string[] leapYearMonthNames = null;
+        private string[]? leapYearMonthNames = null;
 
         // For our "patterns" arrays we have 2 variables, a string and a string[]
         //
@@ -120,25 +121,25 @@ namespace System.Globalization
         // When we initially construct our string[], we set the string to string[0]
 
         // The "default" Date/time patterns
-        private string longDatePattern = null;
-        private string shortDatePattern = null;
-        private string yearMonthPattern = null;
-        private string longTimePattern = null;
-        private string shortTimePattern = null;
+        private string? longDatePattern = null;
+        private string? shortDatePattern = null;
+        private string? yearMonthPattern = null;
+        private string? longTimePattern = null;
+        private string? shortTimePattern = null;
 
-        private string[] allYearMonthPatterns = null;
+        private string[]? allYearMonthPatterns = null;
 
-        private string[] allShortDatePatterns = null;
-        private string[] allLongDatePatterns = null;
-        private string[] allShortTimePatterns = null;
-        private string[] allLongTimePatterns = null;
+        private string[]? allShortDatePatterns = null;
+        private string[]? allLongDatePatterns = null;
+        private string[]? allShortTimePatterns = null;
+        private string[]? allLongTimePatterns = null;
 
         // Cache the era names for this DateTimeFormatInfo instance.
-        private string[] m_eraNames = null;
-        private string[] m_abbrevEraNames = null;
-        private string[] m_abbrevEnglishEraNames = null;
+        private string[]? m_eraNames = null;
+        private string[]? m_abbrevEraNames = null;
+        private string[]? m_abbrevEnglishEraNames = null;
 
-        private CalendarId[] optionalCalendars = null;
+        private CalendarId[]? optionalCalendars = null;
 
         private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
 
@@ -337,7 +338,6 @@ namespace System.Globalization
         /// <summary>
         /// Returns the current culture's DateTimeFormatInfo.
         /// </summary>
-
         public static DateTimeFormatInfo CurrentInfo
         {
             get
@@ -345,24 +345,24 @@ namespace System.Globalization
                 System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture;
                 if (!culture._isInherited)
                 {
-                    DateTimeFormatInfo info = culture._dateTimeInfo;
+                    DateTimeFormatInfo? info = culture._dateTimeInfo;
                     if (info != null)
                     {
                         return info;
                     }
                 }
-                return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
+                return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo))!;
             }
         }
 
-        public static DateTimeFormatInfo GetInstance(IFormatProvider provider) =>
+        public static DateTimeFormatInfo GetInstance(IFormatProvider? provider) =>
             provider == null ? CurrentInfo :
             provider is CultureInfo cultureProvider && !cultureProvider._isInherited ? cultureProvider.DateTimeFormat :
             provider is DateTimeFormatInfo info ? info :
             provider.GetFormat(typeof(DateTimeFormatInfo)) is DateTimeFormatInfo info2 ? info2 :
             CurrentInfo; // Couldn't get anything, just use currentInfo as fallback
 
-        public object GetFormat(Type formatType)
+        public object? GetFormat(Type? formatType)
         {
             return formatType == typeof(DateTimeFormatInfo) ? this : null;
         }
@@ -541,7 +541,7 @@ namespace System.Globalization
             for (int i = 0; i < EraNames.Length; i++)
             {
                 // Compare the era name in a case-insensitive way for the appropriate culture.
-                if (m_eraNames[i].Length > 0)
+                if (m_eraNames![i].Length > 0)
                 {
                     if (Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0)
                     {
@@ -552,7 +552,7 @@ namespace System.Globalization
             for (int i = 0; i < AbbreviatedEraNames.Length; i++)
             {
                 // Compare the abbreviated era name in a case-insensitive way for the appropriate culture.
-                if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0)
+                if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames![i], CompareOptions.IgnoreCase) == 0)
                 {
                     return i + 1;
                 }
@@ -561,7 +561,7 @@ namespace System.Globalization
             {
                 // this comparison should use the InvariantCulture.  The English name could have linguistically
                 // interesting characters.
-                if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames[i], CompareOptions.IgnoreCase) == 0)
+                if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames![i], CompareOptions.IgnoreCase) == 0)
                 {
                     return i + 1;
                 }
@@ -597,7 +597,7 @@ namespace System.Globalization
             // If that ever changes, the code has to be changed.
             if ((--era) < EraNames.Length && (era >= 0))
             {
-                return m_eraNames[era];
+                return m_eraNames![era];
             }
 
             throw new ArgumentOutOfRangeException(nameof(era), era, SR.ArgumentOutOfRange_InvalidEraValue);
@@ -630,7 +630,7 @@ namespace System.Globalization
             {
                 era = Calendar.CurrentEraValue;
             }
-            if ((--era) < m_abbrevEraNames.Length && (era >= 0))
+            if ((--era) < m_abbrevEraNames!.Length && (era >= 0))
             {
                 return m_abbrevEraNames[era];
             }
@@ -738,7 +738,7 @@ namespace System.Globalization
                         value,
                         SR.Format(SR.ArgumentOutOfRange_Range, CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
                 }
-                
+
                 calendarWeekRule = (int)value;
             }
         }
@@ -1255,7 +1255,7 @@ namespace System.Globalization
                 {
                     throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
                 }
-    
+
                 CheckNullValue(value, value.Length);
                 ClearTokenHashTable();
 
@@ -1325,7 +1325,7 @@ namespace System.Globalization
         /// </summary>
         internal string InternalGetMonthName(int month, MonthNameStyles style, bool abbreviated)
         {
-            string[] monthNamesArray = null;
+            string[] monthNamesArray;
             switch (style)
             {
                 case MonthNameStyles.Genitive:
@@ -1474,7 +1474,7 @@ namespace System.Globalization
 
         public string[] GetAllDateTimePatterns(char format)
         {
-            string[] result = null;
+            string[] result;
 
             switch (format)
             {
@@ -1919,14 +1919,14 @@ namespace System.Globalization
         }
 
         // Decimal separator used by positive TimeSpan pattern
-        private string _decimalSeparator;
+        private string? _decimalSeparator;
         internal string DecimalSeparator
         {
             get
             {
                 if (_decimalSeparator == null)
                 {
-                    CultureData cultureDataWithoutUserOverrides = _cultureData.UseUserOverride ?
+                    CultureData? cultureDataWithoutUserOverrides = _cultureData.UseUserOverride ?
                         CultureData.GetCultureData(_cultureData.CultureName, false) :
                         _cultureData;
                     _decimalSeparator = new NumberFormatInfo(cultureDataWithoutUserOverrides).NumberDecimalSeparator;
@@ -1936,7 +1936,7 @@ namespace System.Globalization
         }
 
         // Positive TimeSpan Pattern
-        private string _fullTimeSpanPositivePattern;
+        private string? _fullTimeSpanPositivePattern;
         internal string FullTimeSpanPositivePattern
         {
             get
@@ -1950,7 +1950,7 @@ namespace System.Globalization
         }
 
         // Negative TimeSpan Pattern
-        private string _fullTimeSpanNegativePattern;
+        private string? _fullTimeSpanNegativePattern;
         internal string FullTimeSpanNegativePattern
         {
             get
@@ -2098,7 +2098,7 @@ namespace System.Globalization
         }
 
         // DateTimeFormatInfo tokenizer.  This is used by DateTime.Parse() to break input string into tokens.
-        private TokenHashValue[] _dtfiTokenHash;
+        private TokenHashValue[]? _dtfiTokenHash;
 
         private const int TOKEN_HASH_SIZE = 199;
         private const int SECOND_PRIME = 197;
@@ -2190,7 +2190,7 @@ namespace System.Globalization
 
         internal TokenHashValue[] CreateTokenHashTable()
         {
-            TokenHashValue[] temp = _dtfiTokenHash;
+            TokenHashValue[]? temp = _dtfiTokenHash;
             if (temp == null)
             {
                 temp = new TokenHashValue[TOKEN_HASH_SIZE];
@@ -2263,12 +2263,9 @@ namespace System.Globalization
                     InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.SEP_DateOrOffset, 0);
                 }
 
-                string[] dateWords = null;
-                DateTimeFormatInfoScanner scanner = null;
-
                 // We need to rescan the date words since we're always synthetic
-                scanner = new DateTimeFormatInfoScanner();
-                dateWords = scanner.GetDateWordsOfDTFI(this);
+                DateTimeFormatInfoScanner scanner = new DateTimeFormatInfoScanner();
+                string[]? dateWords = scanner.GetDateWordsOfDTFI(this);
                 // Ensure the formatflags is initialized.
                 DateTimeFormatFlags flag = FormatFlags;
 
@@ -2593,7 +2590,7 @@ namespace System.Globalization
             int remaining = str.Length - str.Index;
             int i = 0;
 
-            TokenHashValue[] hashTable = _dtfiTokenHash;
+            TokenHashValue[]? hashTable = _dtfiTokenHash;
             if (hashTable == null)
             {
                 hashTable = CreateTokenHashTable();
index 99cc413..76ee908 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Globalization;
 using System.Runtime.CompilerServices;
@@ -5110,7 +5111,7 @@ new DS[] { DS.ERROR, DS.TX_NNN,  DS.TX_NNN,  DS.TX_NNN,  DS.ERROR,   DS.ERROR,
                     return new FormatException(SR.Format(SR.GetResourceString(result.failureMessageID), new string(result.originalDateTimeString), result.failureMessageFormatArgument));
                 default:
                     Debug.Fail("Unknown DateTimeParseFailure: " + result.failure.ToString());
-                    return null;
+                    return null!;
             }
         }
 
@@ -5996,7 +5997,7 @@ new DS[] { DS.ERROR, DS.TX_NNN,  DS.TX_NNN,  DS.TX_NNN,  DS.ERROR,   DS.ERROR,
 
         internal ParseFailureKind failure;
         internal string failureMessageID;
-        internal object failureMessageFormatArgument;
+        internal object? failureMessageFormatArgument;
         internal string failureArgumentName;
         internal ReadOnlySpan<char> originalDateTimeString;
         internal ReadOnlySpan<char> failedFormatSpecifier;
@@ -6044,14 +6045,14 @@ new DS[] { DS.ERROR, DS.TX_NNN,  DS.TX_NNN,  DS.TX_NNN,  DS.ERROR,   DS.ERROR,
             this.failureMessageFormatArgument = null;
         }
 
-        internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument)
+        internal void SetFailure(ParseFailureKind failure, string failureMessageID, object? failureMessageFormatArgument)
         {
             this.failure = failure;
             this.failureMessageID = failureMessageID;
             this.failureMessageFormatArgument = failureMessageFormatArgument;
         }
 
-        internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument, string failureArgumentName)
+        internal void SetFailure(ParseFailureKind failure, string failureMessageID, object? failureMessageFormatArgument, string failureArgumentName)
         {
             this.failure = failure;
             this.failureMessageID = failureMessageID;
index 72a572c..0569b39 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 namespace System.Globalization
 {
     // This class represents a starting/ending time for a period of daylight saving time.
index 007283a..ed00cc5 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System;
 using System.Diagnostics;
 
index 28bf46e..68aba7e 100644 (file)
@@ -268,7 +268,7 @@ namespace System.Globalization
 
         public override int GetEra(DateTime time) => ADEra;
 
-        public override int[]? Eras => new int[] { ADEra };
+        public override int[] Eras => new int[] { ADEra };
 
         /// <summary>
         /// Returns the month part of the specified DateTime.
index b7dd868..5889dcb 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System;
 using System.Threading;
 
@@ -19,9 +20,9 @@ namespace System.Globalization
                                    // be affected by the DateTime.MinValue;
         internal int maxEraYear;   // Max year value in this era. (== the year length of the era + 1)
 
-        internal string eraName;    // The era name
-        internal string abbrevEraName;  // Abbreviated Era Name
-        internal string englishEraName; // English era name
+        internal string? eraName;    // The era name
+        internal string? abbrevEraName;  // Abbreviated Era Name
+        internal string? englishEraName; // English era name
 
         internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear)
         {
@@ -111,7 +112,7 @@ namespace System.Globalization
         internal Calendar m_Cal;
 
         internal EraInfo[] m_EraInfo;
-        internal int[] m_eras = null;
+        internal int[]? m_eras = null;
 
 
         // Construct an instance of gregorian calendar.
@@ -668,4 +669,3 @@ namespace System.Globalization
         }
     }
 }
-
index 4975366..314c998 100644 (file)
@@ -696,7 +696,7 @@ namespace System.Globalization
 
         public override int GetEra(DateTime time) => HebrewEra;
 
-        public override int[]? Eras => new int[] { HebrewEra };
+        public override int[] Eras => new int[] { HebrewEra };
 
         public override int GetMonth(DateTime time)
         {
@@ -907,4 +907,3 @@ namespace System.Globalization
         }
     }
 }
-
index db9b379..1919e82 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Text;
 using System.Diagnostics;
 
@@ -222,7 +223,7 @@ namespace System.Globalization
             Digit200_300 = 1,
             Digit100 = 2,
             Digit10 = 3,    // 10 ~ 90
-            Digit1 = 4,     // 1, 2, 3, 4, 5, 8, 
+            Digit1 = 4,     // 1, 2, 3, 4, 5, 8,
             Digit6_7 = 5,
             Digit7 = 6,
             Digit9 = 7,
@@ -262,7 +263,7 @@ namespace System.Globalization
             new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7
             new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8
             new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9;          // Hebrew Letter Yod
-            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da; 
+            new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da;
             new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db;          // Hebrew Letter Kaf
             new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc;          // Hebrew Letter Lamed
             new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd;
@@ -315,7 +316,7 @@ namespace System.Globalization
             END = 100,          // A terminial state is reached.
         }
 
-        // 
+        //
         // The state machine for Hebrew number pasing.
         //
         private static readonly HS[] s_numberPasingState =
@@ -361,7 +362,7 @@ namespace System.Globalization
         private const int HebrewTokenCount = 10;
 
         ////////////////////////////////////////////////////////////////////////
-        //  
+        //
         //  Actions:
         //      Parse the Hebrew number by passing one character at a time.
         //      The state between characters are maintained at HebrewNumberPasingContext.
index f2a8aff..41458c5 100644 (file)
@@ -354,7 +354,7 @@ namespace System.Globalization
             return HijriEra;
         }
 
-        public override int[]? Eras => new int[] { HijriEra };
+        public override int[] Eras => new int[] { HijriEra };
 
         public override int GetMonth(DateTime time)
         {
@@ -422,7 +422,7 @@ namespace System.Globalization
             {
                 throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
             }
-            
+
             return new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond));
         }
 
index 3b3ba15..89f5ca4 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using static System.Globalization.GregorianCalendar;
 
 namespace System.Globalization
@@ -135,7 +136,7 @@ namespace System.Globalization
             int correction = GetWeekday(jan4.DayOfWeek) + 3;
 
             int ordinal = (week * 7) + GetWeekday(dayOfWeek) - correction;
-                
+
             return new DateTime(year, month: 1, day: 1).AddDays(ordinal - 1);
         }
 
index 20f753e..4c8dcb8 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 
 namespace System.Globalization
@@ -122,7 +123,7 @@ namespace System.Globalization
         /// is enabled.
         ///
         /// To match Windows behavior, we walk the string ourselves looking for these
-        /// bad characters so we can continue to throw ArgumentException in these cases. 
+        /// bad characters so we can continue to throw ArgumentException in these cases.
         /// </summary>
         private static unsafe void CheckInvalidIdnCharacters(char* s, int count, uint flags, string paramName)
         {
index 9d491df..696abbc 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
@@ -119,10 +120,9 @@ namespace System.Globalization
             int lastError = Marshal.GetLastWin32Error();
 
             throw new ArgumentException(
-                lastError == Interop.Errors.ERROR_INVALID_NAME ? SR.Argument_IdnIllegalName : 
+                lastError == Interop.Errors.ERROR_INVALID_NAME ? SR.Argument_IdnIllegalName :
                     (unicode ? SR.Argument_InvalidCharSequenceNoIndex : SR.Argument_IdnBadPunycode),
                 unicode ? "unicode" : "ascii");
         }
     }
 }
-
index 56f38ff..9da4411 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 // This file contains the IDN functions and implementation.
 //
 // This allows encoding of non-ASCII domain names in a "punycode" form,
@@ -143,7 +144,7 @@ namespace System.Globalization
             }
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             return
                 obj is IdnMapping that &&
index 6dc2b19..59fcd0f 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 namespace System.Globalization
 {
     internal class InternalGlobalizationHelper
index 84bcedb..364eeef 100644 (file)
@@ -17,13 +17,13 @@ namespace System.Globalization
                 return null;
             }
 
-            string[] eraNames;
+            string[]? eraNames;
             if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames))
             {
                 return null;
             }
 
-            string[] abbrevEnglishEraNames;
+            string[]? abbrevEnglishEraNames;
             if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames))
             {
                 return null;
@@ -48,7 +48,7 @@ namespace System.Globalization
                 }
 
                 eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1,
-                    eraNames[i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames[i]));
+                    eraNames![i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames![i]));
 
                 lastMaxYear = dt.Year;
             }
index 090d095..63a0f50 100644 (file)
@@ -114,7 +114,7 @@ namespace System.Globalization
         {
             return _helper.AddYears(time, years);
         }
-        
+
         public override int GetDaysInMonth(int year, int month, int era)
         {
             return _helper.GetDaysInMonth(year, month, era);
@@ -213,7 +213,7 @@ namespace System.Globalization
         }
 
 
-        public override int[]? Eras => _helper.Eras;
+        public override int[] Eras => _helper.Eras;
 
         /// <summary>
         /// Return the various era strings
@@ -227,7 +227,7 @@ namespace System.Globalization
             for (int i = 0; i < eras.Length; i++)
             {
                 // Strings are in chronological order, eras are backwards order.
-                eraNames[i] = eras[eras.Length - i - 1].eraName;
+                eraNames[i] = eras[eras.Length - i - 1].eraName!;
             }
 
             return eraNames;
@@ -241,7 +241,7 @@ namespace System.Globalization
             for (int i = 0; i < eras.Length; i++)
             {
                 // Strings are in chronological order, eras are backwards order.
-                erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName;
+                erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName!;
             }
 
             return erasAbbrev;
@@ -255,7 +255,7 @@ namespace System.Globalization
             for (int i = 0; i < eras.Length; i++)
             {
                 // Strings are in chronological order, eras are backwards order.
-                erasEnglish[i] = eras[eras.Length - i - 1].englishEraName;
+                erasEnglish[i] = eras[eras.Length - i - 1].englishEraName!;
             }
 
             return erasEnglish;
index db1fd4f..89e4e2b 100644 (file)
@@ -27,7 +27,7 @@ namespace System.Globalization
         public override DateTime MinSupportedDateTime => s_minDate;
 
         public override DateTime MaxSupportedDateTime => s_maxDate;
-        
+
         protected override int DaysInYearBeforeMinSupportedYear
         {
             get
@@ -217,6 +217,6 @@ namespace System.Globalization
 
         internal override CalendarId ID => CalendarId.JAPANESELUNISOLAR;
 
-        public override int[]? Eras => _helper.Eras;
+        public override int[] Eras => _helper.Eras;
     }
 }
index 79a0625..782e197 100644 (file)
@@ -267,7 +267,7 @@ namespace System.Globalization
             return GetDatePart(time.Ticks, DatePartMonth);
         }
 
-        public override int[]? Eras => new int[] { JulianEra };
+        public override int[] Eras => new int[] { JulianEra };
 
         public override int GetMonthsInYear(int year, int era)
         {
index 4fbaa9f..a29f4d2 100644 (file)
@@ -144,7 +144,7 @@ namespace System.Globalization
             return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era);
         }
 
-        public override int[]? Eras => _helper.Eras;
+        public override int[] Eras => _helper.Eras;
 
         private const int DefaultTwoDigitYearMax = 4362;
 
index b7feb1a..5871436 100644 (file)
@@ -1236,6 +1236,6 @@ namespace System.Globalization
 
         internal override CalendarId ID => CalendarId.KOREANLUNISOLAR;
 
-        public override int[]? Eras => new int[] { GregorianEra };
+        public override int[] Eras => new int[] { GregorianEra };
     }
 }
index 2bd3d79..6b5049c 100644 (file)
@@ -2,9 +2,10 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 
-// This file contains the handling of Windows OS specific culture features.  
+// This file contains the handling of Windows OS specific culture features.
 
 namespace System.Globalization
 {
@@ -15,12 +16,12 @@ namespace System.Globalization
         OemCodePage = 2,
         MacCodePage = 3,
         EbcdicCodePage = 4,
-        GeoId = 5, 
-        DigitSubstitution = 6, 
-        SpecificLocaleIndex = 7, 
+        GeoId = 5,
+        DigitSubstitution = 6,
+        SpecificLocaleIndex = 7,
         ConsoleLocaleIndex = 8
     }
-    
+
     internal partial class LocaleData
     {
         // this is done rather than using a large readonly array of strings to avoid
@@ -894,10 +895,10 @@ namespace System.Globalization
             "zh-tw_radstr"            + //  40404 - 4265
             "zu"                      + //  00035 - 4277
             "zu-za";                    //  00435 - 4279
-        
+
         // c_threeLetterWindowsLanguageName is string containing 3-letter Windows language names
-        // every 3-characters entry is matching locale name entry in c_localeNames 
-        
+        // every 3-characters entry is matching locale name entry in c_localeNames
+
         private const string c_threeLetterWindowsLanguageName =
             "ZZZ" + // aa
             "ZZZ" + // aa-dj
@@ -2636,7 +2637,7 @@ namespace System.Globalization
             4279,  // 863  - zu-za
             4284
         };
-               
+
         private const int NUMERIC_LOCALE_DATA_COUNT_PER_ROW = 9;
         // s_nameIndexToNumericData is mapping from index in s_localeNamesIndices to locale data.
         // each row in the table will have the following data:
@@ -3510,7 +3511,7 @@ namespace System.Globalization
             0x435  , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1  , 1 , 863 , 863 , // 863  - zu-za
         };
 
-        // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to 
+        // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to
         // get the index in s_localeNamesIndices using s_lcidToCultureNameIndices
         private static readonly int[] s_lcids = new int[]
         {
@@ -3963,7 +3964,7 @@ namespace System.Globalization
             0x41404, // 445  - 4195
             0x50804, // 446  - 4115
             0x51004  // 447  - 4224
-        };        
+        };
         // each element in s_lcidToCultureNameIndices is index to s_localeNamesIndices
         private static readonly int[] s_lcidToCultureNameIndices = new int[]
         {
@@ -4417,8 +4418,8 @@ namespace System.Globalization
             845  , // 446  - 50804 - 4115
             857    // 447  - 51004 - 4224
         };
-          
-        internal static string LCIDToLocaleName(int culture)
+
+        internal static string? LCIDToLocaleName(int culture)
         {
             int left = 0;
             int right = s_lcids.Length - 1;
@@ -4434,9 +4435,9 @@ namespace System.Globalization
                 {
                     int indexToLocaleNamesIndices = s_lcidToCultureNameIndices[index];
                     Debug.Assert(indexToLocaleNamesIndices < s_localeNamesIndices.Length - 1);
-                    
-                    return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices], 
-                                                                         s_localeNamesIndices[indexToLocaleNamesIndices + 1] - 
+
+                    return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices],
+                                                                         s_localeNamesIndices[indexToLocaleNamesIndices + 1] -
                                                                          s_localeNamesIndices[indexToLocaleNamesIndices]);
                 }
                 else if (culture < s_lcids[index])
@@ -4457,27 +4458,27 @@ namespace System.Globalization
             int index = SearchCultureName(cultureName);
             if (index < 0)
             {
-                return -1; 
+                return -1;
             }
-            
-            Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) && 
+
+            Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) &&
                             index < s_localeNamesIndices.Length);
-            
+
             return s_nameIndexToNumericData[index * NUMERIC_LOCALE_DATA_COUNT_PER_ROW + (int) part];
         }
-        
-        internal static string GetThreeLetterWindowsLanguageName(string cultureName)
+
+        internal static string? GetThreeLetterWindowsLanguageName(string cultureName)
         {
             int index = SearchCultureName(cultureName);
             if (index < 0)
             {
                 return null;
             }
-            
+
             Debug.Assert(s_localeNamesIndices.Length-1 == (c_threeLetterWindowsLanguageName.Length / 3));
-            return c_threeLetterWindowsLanguageName.Substring(index * 3, 3); 
+            return c_threeLetterWindowsLanguageName.Substring(index * 3, 3);
         }
-        
+
         internal static string GetLocaleDataMappedCulture(string cultureName, LocaleDataParts part)
         {
             int indexToIndicesTable = GetLocaleDataNumericPart(cultureName, part);
@@ -4485,25 +4486,25 @@ namespace System.Globalization
             {
                 return ""; // fallback to invariant
             }
-            
+
             Debug.Assert(indexToIndicesTable < s_localeNamesIndices.Length-1);
-            
-            return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable], 
+
+            return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable],
                                            s_localeNamesIndices[indexToIndicesTable+1] - s_localeNamesIndices[indexToIndicesTable]);
         }
-        
+
         internal static string GetSpecificCultureName(string cultureName)
         {
             return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.SpecificLocaleIndex);
         }
-        
+
         internal static string GetConsoleUICulture(string cultureName)
         {
             return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.ConsoleLocaleIndex);
         }
-        
+
         // SearchCultureName will binary search c_localeNames using s_localeNamesIndices.
-        // return index in s_localeNamesIndices, or -1 if it fail finding any match   
+        // return index in s_localeNamesIndices, or -1 if it fail finding any match
         private static int SearchCultureName(string name)
         {
             int left = 0;
@@ -4550,7 +4551,7 @@ namespace System.Globalization
             // couldn't find culture name
             return -1;
         }
-        
+
         // optimized to avoid parameters checking
         private static int CompareOrdinal(string s1, string s2, int index, int length)
         {
index 443dbae..79a2832 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Text;
 
@@ -13,7 +14,7 @@ namespace System.Globalization
         {
             if (GlobalizationMode.Invariant)
             {
-                // In Invariant mode we assume all characters are normalized. 
+                // In Invariant mode we assume all characters are normalized.
                 // This is because we don't support any linguistic operation on the strings
                 return true;
             }
@@ -34,7 +35,7 @@ namespace System.Globalization
         {
             if (GlobalizationMode.Invariant)
             {
-                // In Invariant mode we assume all characters are normalized. 
+                // In Invariant mode we assume all characters are normalized.
                 // This is because we don't support any linguistic operation on the strings
                 return strInput;
             }
@@ -95,7 +96,7 @@ namespace System.Globalization
             for (int i = 0; i < s.Length; i++)
             {
                 char c = s[i];
-                
+
                 if (c < '\ud800')
                 {
                     continue;
index 8418c53..0b3ce0e 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Text;
@@ -14,7 +15,7 @@ namespace System.Globalization
         {
             if (GlobalizationMode.Invariant)
             {
-                // In Invariant mode we assume all characters are normalized. 
+                // In Invariant mode we assume all characters are normalized.
                 // This is because we don't support any linguistic operation on the strings
                 return true;
             }
@@ -22,7 +23,7 @@ namespace System.Globalization
             Debug.Assert(strInput != null);
 
             // The only way to know if IsNormalizedString failed is through checking the Win32 last error
-            // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error 
+            // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error
             // to 0 (ERROR_SUCCESS) before executing the calls.
             bool result = Interop.Normaliz.IsNormalizedString((int)normalizationForm, strInput, strInput.Length);
 
@@ -34,9 +35,9 @@ namespace System.Globalization
 
                 case Interop.Errors.ERROR_INVALID_PARAMETER:
                 case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
-                    if (normalizationForm != NormalizationForm.FormC && 
-                        normalizationForm != NormalizationForm.FormD && 
-                        normalizationForm != NormalizationForm.FormKC && 
+                    if (normalizationForm != NormalizationForm.FormC &&
+                        normalizationForm != NormalizationForm.FormD &&
+                        normalizationForm != NormalizationForm.FormKC &&
                         normalizationForm != NormalizationForm.FormKD)
                     {
                         throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
@@ -58,7 +59,7 @@ namespace System.Globalization
         {
             if (GlobalizationMode.Invariant)
             {
-                // In Invariant mode we assume all characters are normalized. 
+                // In Invariant mode we assume all characters are normalized.
                 // This is because we don't support any linguistic operation on the strings
                 return strInput;
             }
@@ -66,7 +67,7 @@ namespace System.Globalization
             Debug.Assert(strInput != null);
 
             // we depend on Win32 last error when calling NormalizeString
-            // NormalizeString pinvoke has SetLastError attribute property which will set the last error 
+            // NormalizeString pinvoke has SetLastError attribute property which will set the last error
             // to 0 (ERROR_SUCCESS) before executing the calls.
 
             // Guess our buffer size first
@@ -78,9 +79,9 @@ namespace System.Globalization
             {
                 if (lastError == Interop.Errors.ERROR_INVALID_PARAMETER)
                 {
-                    if (normalizationForm != NormalizationForm.FormC && 
-                        normalizationForm != NormalizationForm.FormD && 
-                        normalizationForm != NormalizationForm.FormKC && 
+                    if (normalizationForm != NormalizationForm.FormC &&
+                        normalizationForm != NormalizationForm.FormD &&
+                        normalizationForm != NormalizationForm.FormKC &&
                         normalizationForm != NormalizationForm.FormKD)
                     {
                         throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
@@ -103,14 +104,14 @@ namespace System.Globalization
             if (iLength == 0) return string.Empty;
 
             // Someplace to stick our buffer
-            char[] cBuffer = null;
+            char[] cBuffer;
 
             for (;;)
             {
                 // (re)allocation buffer and normalize string
                 cBuffer = new char[iLength];
 
-                // NormalizeString pinvoke has SetLastError attribute property which will set the last error 
+                // NormalizeString pinvoke has SetLastError attribute property which will set the last error
                 // to 0 (ERROR_SUCCESS) before executing the calls.
                 iLength = Interop.Normaliz.NormalizeString((int)normalizationForm, strInput, strInput.Length, cBuffer, cBuffer.Length);
                 lastError = Marshal.GetLastWin32Error();
index a312d29..bd490e4 100644 (file)
@@ -164,7 +164,7 @@ namespace System.Globalization
             _hasInvariantNumberSigns = _positiveSign == "+" && _negativeSign == "-";
         }
 
-        internal NumberFormatInfo(CultureData cultureData)
+        internal NumberFormatInfo(CultureData? cultureData)
         {
             if (cultureData != null)
             {
index 0858379..0e43b15 100644 (file)
@@ -282,7 +282,7 @@ namespace System.Globalization
             return PersianEra;
         }
 
-        public override int[]? Eras => new int[] { PersianEra };
+        public override int[] Eras => new int[] { PersianEra };
 
         public override int GetMonth(DateTime time)
         {
index 03bed85..b638b2a 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 
 namespace System.Globalization
@@ -15,13 +16,13 @@ namespace System.Globalization
     public class RegionInfo
     {
         // Name of this region (ie: es-US): serialized, the field used for deserialization
-        private string _name;
+        private string _name = null!;
 
         // The CultureData instance that we are going to read data from.
         private readonly CultureData _cultureData;
 
         // The RegionInfo for our current region
-        internal static volatile RegionInfo s_currentRegionInfo;
+        internal static volatile RegionInfo? s_currentRegionInfo;
 
         public RegionInfo(string name)
         {
@@ -37,11 +38,8 @@ namespace System.Globalization
             }
 
             // For CoreCLR we only want the region names that are full culture names
-            _cultureData = CultureData.GetCultureDataForRegion(name, true);
-            if (_cultureData == null)
-            {
+            _cultureData = CultureData.GetCultureDataForRegion(name, true) ??
                 throw new ArgumentException(SR.Format(SR.Argument_InvalidCultureName, name), nameof(name));
-            }
 
             // Not supposed to be neutral
             if (_cultureData.IsNeutralCulture)
@@ -102,7 +100,7 @@ namespace System.Globalization
         {
             get
             {
-                RegionInfo temp = s_currentRegionInfo;
+                RegionInfo? temp = s_currentRegionInfo;
                 if (temp == null)
                 {
                     temp = new RegionInfo(CultureInfo.CurrentCulture._cultureData);
@@ -194,7 +192,7 @@ namespace System.Globalization
         /// RegionInfos are considered equal if and only if they have the same name
         /// (ie: en-US)
         /// </summary>
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             return value is RegionInfo otherRegion
                 && Name.Equals(otherRegion.Name);
index ce86d56..23cf8b3 100644 (file)
@@ -2,13 +2,14 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Runtime.CompilerServices;
 
 namespace System.Globalization
 {
     [Serializable]
     [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
-    public sealed class SortVersion : IEquatable<SortVersion>
+    public sealed class SortVersion : IEquatable<SortVersion?>
     {
         private int m_NlsVersion; // Do not rename (binary serialization)
         private Guid m_SortId; // Do not rename (binary serialization)
@@ -39,12 +40,12 @@ namespace System.Globalization
             m_SortId = customVersion;
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             return obj is SortVersion otherVersion && Equals(otherVersion);
         }
 
-        public bool Equals(SortVersion other)
+        public bool Equals(SortVersion? other)
         {
             if (other == null)
             {
@@ -61,7 +62,7 @@ namespace System.Globalization
 
         // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static bool operator ==(SortVersion left, SortVersion right)
+        public static bool operator ==(SortVersion? left, SortVersion? right)
         {
             // Test "right" first to allow branch elimination when inlined for null checks (== null)
             // so it can become a simple test
@@ -74,7 +75,7 @@ namespace System.Globalization
             return right.Equals(left);
         }
 
-        public static bool operator !=(SortVersion left, SortVersion right)
+        public static bool operator !=(SortVersion? left, SortVersion? right)
         {
             return !(left == right);
         }
index a4282dc..ef2efb9 100644 (file)
@@ -14,7 +14,7 @@ namespace System.Globalization
     /// </summary>
     public class StringInfo
     {
-        private string _str;
+        private string _str = null!;
 
         private int[]? _indexes;
 
@@ -24,7 +24,6 @@ namespace System.Globalization
 
         public StringInfo(string value)
         {
-            _str = null!;
             this.String = value;
         }
 
index 6d7fb41..de541a3 100644 (file)
@@ -28,7 +28,7 @@ namespace System.Globalization
         //  So yearOffset = 1911
         private static EraInfo[] s_taiwanEraInfo = new EraInfo[]
         {
-            new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911)    // era #, start year/month/day, yearOffset, minEraYear 
+            new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911)    // era #, start year/month/day, yearOffset, minEraYear
         };
 
         private static volatile Calendar s_defaultInstance;
@@ -149,7 +149,7 @@ namespace System.Globalization
             return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era);
         }
 
-        public override int[]? Eras => _helper.Eras;
+        public override int[] Eras => _helper.Eras;
 
         private const int DefaultTwoDigitYearMax = 99;
 
index 826f0f3..47dbc3b 100644 (file)
@@ -21,7 +21,7 @@ namespace System.Globalization
         //  So yearOffset = 1911
         private static readonly EraInfo[] s_taiwanLunisolarEraInfo = new EraInfo[]
         {
-            new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911)    // era #, start year/month/day, yearOffset, minEraYear 
+            new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911)    // era #, start year/month/day, yearOffset, minEraYear
         };
 
         private readonly GregorianCalendarHelper _helper;
@@ -235,6 +235,6 @@ namespace System.Globalization
 
         internal override CalendarId ID => CalendarId.TAIWANLUNISOLAR;
 
-        public override int[]? Eras => _helper.Eras;
+        public override int[] Eras => _helper.Eras;
     }
 }
index 45cf55c..5f75e6c 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Security;
index d0c8594..b59648d 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 
 namespace System.Globalization
index 12ce6d9..cf89dff 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
@@ -33,7 +34,7 @@ namespace System.Globalization
             True = 2
         }
 
-        private string _listSeparator;
+        private string? _listSeparator;
         private bool _isReadOnly = false;
 
         private readonly string _cultureName;
@@ -50,7 +51,7 @@ namespace System.Globalization
             get => s_invariant ?? (s_invariant = new TextInfo(CultureData.Invariant));
         }
 
-        private volatile static TextInfo s_invariant;
+        private volatile static TextInfo? s_invariant;
 
         internal TextInfo(CultureData cultureData)
         {
@@ -602,7 +603,7 @@ namespace System.Globalization
         /// </summary>
         public bool IsRightToLeft => _cultureData.IsRightToLeft;
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             return obj is TextInfo otherTextInfo
                 && CultureName.Equals(otherTextInfo.CultureName);
@@ -640,7 +641,7 @@ namespace System.Globalization
             }
 
             StringBuilder result = new StringBuilder();
-            string lowercaseData = null;
+            string? lowercaseData = null;
             // Store if the current culture is Dutch (special case)
             bool isDutchCulture = CultureName.StartsWith("nl-", StringComparison.OrdinalIgnoreCase);
 
index 1b39c7b..8997f00 100644 (file)
@@ -125,7 +125,7 @@ namespace System.Globalization
             return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era);
         }
 
-        public override int[]? Eras => _helper.Eras;
+        public override int[] Eras => _helper.Eras;
 
         private const int DefaultTwoDigitYearMax = 2572;
 
index 8af839f..49d7e89 100644 (file)
@@ -520,7 +520,7 @@ namespace System.Globalization
             return UmAlQuraEra;
         }
 
-        public override int[]? Eras => new int[] { UmAlQuraEra };
+        public override int[] Eras => new int[] { UmAlQuraEra };
 
         public override int GetMonth(DateTime time)
         {