Seal CompareInfo and TextInfo (#31761)
authorLevi Broderick <GrabYourPitchforks@users.noreply.github.com>
Wed, 5 Feb 2020 02:15:35 +0000 (18:15 -0800)
committerGitHub <noreply@github.com>
Wed, 5 Feb 2020 02:15:35 +0000 (18:15 -0800)
src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/SortKey.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs
src/libraries/System.Private.CoreLib/src/System/StringComparer.cs
src/libraries/System.Runtime/ref/System.Runtime.cs

index 3be3711..50336fe 100644 (file)
@@ -17,7 +17,7 @@ namespace System.Globalization
     /// </summary>
     [Serializable]
     [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
-    public partial class CompareInfo : IDeserializationCallback
+    public sealed partial class CompareInfo : IDeserializationCallback
     {
         // Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags.
         private const CompareOptions ValidIndexMaskOffFlags =
@@ -29,7 +29,7 @@ namespace System.Globalization
             ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
               CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
 
-        // Mask used to check if GetHashCodeOfString() has the right flags.
+        // Mask used to check if GetHashCode(string) has the right flags.
         private const CompareOptions ValidHashCodeOfStringMaskOffFlags =
             ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
               CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType);
@@ -218,7 +218,7 @@ 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
+        public string Name
         {
             get
             {
@@ -238,12 +238,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 int Compare(string? string1, string? string2)
         {
             return Compare(string1, string2, CompareOptions.None);
         }
 
-        public virtual int Compare(string? string1, string? string2, CompareOptions options)
+        public int Compare(string? string1, string? string2, CompareOptions options)
         {
             if (options == CompareOptions.OrdinalIgnoreCase)
             {
@@ -369,23 +369,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 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 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 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 int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2, CompareOptions options)
         {
             if (options == CompareOptions.OrdinalIgnoreCase)
             {
@@ -684,7 +684,7 @@ namespace System.Globalization
         /// Determines whether prefix is a prefix of string.  If prefix equals
         /// string.Empty, true is returned.
         /// </summary>
-        public virtual bool IsPrefix(string source, string prefix, CompareOptions options)
+        public bool IsPrefix(string source, string prefix, CompareOptions options)
         {
             if (source == null)
             {
@@ -738,7 +738,7 @@ namespace System.Globalization
             return StartsWith(source, prefix, options);
         }
 
-        public virtual bool IsPrefix(string source, string prefix)
+        public bool IsPrefix(string source, string prefix)
         {
             return IsPrefix(source, prefix, 0);
         }
@@ -747,7 +747,7 @@ namespace System.Globalization
         /// Determines whether suffix is a suffix of string.  If suffix equals
         /// string.Empty, true is returned.
         /// </summary>
-        public virtual bool IsSuffix(string source, string suffix, CompareOptions options)
+        public bool IsSuffix(string source, string suffix, CompareOptions options)
         {
             if (source == null)
             {
@@ -801,7 +801,7 @@ namespace System.Globalization
             return EndsWith(source, suffix, options);
         }
 
-        public virtual bool IsSuffix(string source, string suffix)
+        public bool IsSuffix(string source, string suffix)
         {
             return IsSuffix(source, suffix, 0);
         }
@@ -814,7 +814,7 @@ namespace System.Globalization
         /// endIndex is less than zero or greater than the length of string.
         /// Throws ArgumentException if value is null.
         /// </summary>
-        public virtual int IndexOf(string source, char value)
+        public int IndexOf(string source, char value)
         {
             if (source == null)
             {
@@ -824,7 +824,7 @@ namespace System.Globalization
             return IndexOf(source, value, 0, source.Length, CompareOptions.None);
         }
 
-        public virtual int IndexOf(string source, string value)
+        public int IndexOf(string source, string value)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -832,7 +832,7 @@ namespace System.Globalization
             return IndexOf(source, value, 0, source.Length, CompareOptions.None);
         }
 
-        public virtual int IndexOf(string source, char value, CompareOptions options)
+        public int IndexOf(string source, char value, CompareOptions options)
         {
             if (source == null)
             {
@@ -842,7 +842,7 @@ namespace System.Globalization
             return IndexOf(source, value, 0, source.Length, options);
         }
 
-        public virtual int IndexOf(string source, string value, CompareOptions options)
+        public int IndexOf(string source, string value, CompareOptions options)
         {
             if (source == null)
             {
@@ -852,7 +852,7 @@ namespace System.Globalization
             return IndexOf(source, value, 0, source.Length, options);
         }
 
-        public virtual int IndexOf(string source, char value, int startIndex)
+        public int IndexOf(string source, char value, int startIndex)
         {
             if (source == null)
             {
@@ -862,7 +862,7 @@ namespace System.Globalization
             return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
         }
 
-        public virtual int IndexOf(string source, string value, int startIndex)
+        public int IndexOf(string source, string value, int startIndex)
         {
             if (source == null)
                 throw new ArgumentNullException(nameof(source));
@@ -870,7 +870,7 @@ namespace System.Globalization
             return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
         }
 
-        public virtual int IndexOf(string source, char value, int startIndex, CompareOptions options)
+        public int IndexOf(string source, char value, int startIndex, CompareOptions options)
         {
             if (source == null)
             {
@@ -880,7 +880,7 @@ namespace System.Globalization
             return IndexOf(source, value, startIndex, source.Length - startIndex, options);
         }
 
-        public virtual int IndexOf(string source, string value, int startIndex, CompareOptions options)
+        public int IndexOf(string source, string value, int startIndex, CompareOptions options)
         {
             if (source == null)
             {
@@ -890,17 +890,17 @@ namespace System.Globalization
             return IndexOf(source, value, startIndex, source.Length - startIndex, options);
         }
 
-        public virtual int IndexOf(string source, char value, int startIndex, int count)
+        public int IndexOf(string source, char value, int startIndex, int count)
         {
             return IndexOf(source, value, startIndex, count, CompareOptions.None);
         }
 
-        public virtual int IndexOf(string source, string value, int startIndex, int count)
+        public int IndexOf(string source, string value, int startIndex, int count)
         {
             return IndexOf(source, value, startIndex, count, CompareOptions.None);
         }
 
-        public virtual unsafe int IndexOf(string source, char value, int startIndex, int count, CompareOptions options)
+        public unsafe int IndexOf(string source, char value, int startIndex, int count, CompareOptions options)
         {
             if (source == null)
             {
@@ -930,7 +930,7 @@ namespace System.Globalization
             return IndexOf(source, char.ToString(value), startIndex, count, options, null);
         }
 
-        public virtual unsafe int IndexOf(string source, string value, int startIndex, int count, CompareOptions options)
+        public unsafe int IndexOf(string source, string value, int startIndex, int count, CompareOptions options)
         {
             if (source == null)
             {
@@ -1149,7 +1149,7 @@ namespace System.Globalization
         /// endIndex is less than zero or greater than the length of string.
         /// Throws ArgumentException if value is null.
         /// </summary>
-        public virtual int LastIndexOf(string source, char value)
+        public int LastIndexOf(string source, char value)
         {
             if (source == null)
             {
@@ -1160,7 +1160,7 @@ namespace System.Globalization
             return LastIndexOf(source, value, source.Length - 1, source.Length, CompareOptions.None);
         }
 
-        public virtual int LastIndexOf(string source, string value)
+        public int LastIndexOf(string source, string value)
         {
             if (source == null)
             {
@@ -1172,7 +1172,7 @@ namespace System.Globalization
                 source.Length, CompareOptions.None);
         }
 
-        public virtual int LastIndexOf(string source, char value, CompareOptions options)
+        public int LastIndexOf(string source, char value, CompareOptions options)
         {
             if (source == null)
             {
@@ -1183,7 +1183,7 @@ namespace System.Globalization
             return LastIndexOf(source, value, source.Length - 1, source.Length, options);
         }
 
-        public virtual int LastIndexOf(string source, string value, CompareOptions options)
+        public int LastIndexOf(string source, string value, CompareOptions options)
         {
             if (source == null)
             {
@@ -1194,37 +1194,37 @@ namespace System.Globalization
             return LastIndexOf(source, value, source.Length - 1, source.Length, options);
         }
 
-        public virtual int LastIndexOf(string source, char value, int startIndex)
+        public int LastIndexOf(string source, char value, int startIndex)
         {
             return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
         }
 
-        public virtual int LastIndexOf(string source, string value, int startIndex)
+        public int LastIndexOf(string source, string value, int startIndex)
         {
             return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
         }
 
-        public virtual int LastIndexOf(string source, char value, int startIndex, CompareOptions options)
+        public int LastIndexOf(string source, char value, int startIndex, CompareOptions options)
         {
             return LastIndexOf(source, value, startIndex, startIndex + 1, options);
         }
 
-        public virtual int LastIndexOf(string source, string value, int startIndex, CompareOptions options)
+        public int LastIndexOf(string source, string value, int startIndex, CompareOptions options)
         {
             return LastIndexOf(source, value, startIndex, startIndex + 1, options);
         }
 
-        public virtual int LastIndexOf(string source, char value, int startIndex, int count)
+        public int LastIndexOf(string source, char value, int startIndex, int count)
         {
             return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
         }
 
-        public virtual int LastIndexOf(string source, string value, int startIndex, int count)
+        public int LastIndexOf(string source, string value, int startIndex, int count)
         {
             return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
         }
 
-        public virtual int LastIndexOf(string source, char value, int startIndex, int count, CompareOptions options)
+        public int LastIndexOf(string source, char value, int startIndex, int count, CompareOptions options)
         {
             if (source == null)
             {
@@ -1280,7 +1280,7 @@ namespace System.Globalization
             return LastIndexOfCore(source, value.ToString(), startIndex, count, options);
         }
 
-        public virtual int LastIndexOf(string source, string value, int startIndex, int count, CompareOptions options)
+        public int LastIndexOf(string source, string value, int startIndex, int count, CompareOptions options)
         {
             if (source == null)
             {
@@ -1356,7 +1356,7 @@ namespace System.Globalization
         /// <summary>
         /// Gets the SortKey for the given string with the given options.
         /// </summary>
-        public virtual SortKey GetSortKey(string source, CompareOptions options)
+        public SortKey GetSortKey(string source, CompareOptions options)
         {
             if (GlobalizationMode.Invariant)
             {
@@ -1366,7 +1366,7 @@ namespace System.Globalization
             return CreateSortKey(source, options);
         }
 
-        public virtual SortKey GetSortKey(string source)
+        public SortKey GetSortKey(string source)
         {
             if (GlobalizationMode.Invariant)
             {
@@ -1385,26 +1385,15 @@ namespace System.Globalization
         public override int GetHashCode() => Name.GetHashCode();
 
         /// <summary>
-        /// This internal method allows a method that allows the equivalent of creating a Sortkey for a
-        /// string from CompareInfo, and generate a hashcode value from it.  It is not very convenient
-        /// to use this method as is and it creates an unnecessary Sortkey object that will be GC'ed.
+        /// This method performs the equivalent of of creating a Sortkey for a string from CompareInfo,
+        /// then generates a randomized hashcode value from the sort key.
         ///
         /// The hash code is guaranteed to be the same for string A and B where A.Equals(B) is true and both
         /// the CompareInfo and the CompareOptions are the same. If two different CompareInfo objects
         /// treat the string the same way, this implementation will treat them differently (the same way that
         /// Sortkey does at the moment).
-        ///
-        /// This method will never be made public itself, but public consumers of it could be created, e.g.:
-        ///
-        ///     string.GetHashCode(CultureInfo)
-        ///     string.GetHashCode(CompareInfo)
-        ///     string.GetHashCode(CultureInfo, CompareOptions)
-        ///     string.GetHashCode(CompareInfo, CompareOptions)
-        ///     etc.
-        ///
-        /// (the methods above that take a CultureInfo would use CultureInfo.CompareInfo)
         /// </summary>
-        internal int GetHashCodeOfString(string source, CompareOptions options)
+        public int GetHashCode(string source, CompareOptions options)
         {
             if (source == null)
             {
@@ -1437,12 +1426,6 @@ namespace System.Globalization
             }
         }
 
-        public virtual int GetHashCode(string source, CompareOptions options)
-        {
-            // virtual method delegates to non-virtual method
-            return GetHashCodeOfString(source, options);
-        }
-
         public int GetHashCode(ReadOnlySpan<char> source, CompareOptions options)
         {
             if ((options & ValidHashCodeOfStringMaskOffFlags) == 0)
index b69cf9f..89b12a1 100644 (file)
@@ -99,7 +99,7 @@ namespace System.Globalization
 
         public override int GetHashCode()
         {
-            return CompareInfo.GetCompareInfo(_localeName).GetHashCodeOfString(_string, _options);
+            return CompareInfo.GetCompareInfo(_localeName).GetHashCode(_string, _options);
         }
 
         public override string ToString()
index 56665f7..348c05c 100644 (file)
@@ -24,7 +24,7 @@ namespace System.Globalization
     /// A writing system is the collection of scripts and orthographic rules
     /// required to represent a language as text.
     /// </summary>
-    public partial class TextInfo : ICloneable, IDeserializationCallback
+    public sealed partial class TextInfo : ICloneable, IDeserializationCallback
     {
         private enum Tristate : byte
         {
@@ -64,13 +64,13 @@ namespace System.Globalization
             throw new PlatformNotSupportedException();
         }
 
-        public virtual int ANSICodePage => _cultureData.ANSICodePage;
+        public int ANSICodePage => _cultureData.ANSICodePage;
 
-        public virtual int OEMCodePage => _cultureData.OEMCodePage;
+        public int OEMCodePage => _cultureData.OEMCodePage;
 
-        public virtual int MacCodePage => _cultureData.MacCodePage;
+        public int MacCodePage => _cultureData.MacCodePage;
 
-        public virtual int EBCDICCodePage => _cultureData.EBCDICCodePage;
+        public int EBCDICCodePage => _cultureData.EBCDICCodePage;
 
         // Just use the LCID from our text info name
         public int LCID => CultureInfo.GetCultureInfo(_textInfoName).LCID;
@@ -79,7 +79,7 @@ namespace System.Globalization
 
         public bool IsReadOnly => _isReadOnly;
 
-        public virtual object Clone()
+        public object Clone()
         {
             object o = MemberwiseClone();
             ((TextInfo)o).SetReadOnlyState(false);
@@ -123,7 +123,7 @@ namespace System.Globalization
         /// <summary>
         /// Returns the string used to separate items in a list.
         /// </summary>
-        public virtual string ListSeparator
+        public string ListSeparator
         {
             get => _listSeparator ??= _cultureData.ListSeparator;
             set
@@ -142,7 +142,7 @@ namespace System.Globalization
         /// Converts the character or string to lower case.  Certain locales
         /// have different casing semantics from the file systems in Win32.
         /// </summary>
-        public virtual char ToLower(char c)
+        public char ToLower(char c)
         {
             if (GlobalizationMode.Invariant || (IsAscii(c) && IsAsciiCasingSameAsInvariant))
             {
@@ -152,7 +152,7 @@ namespace System.Globalization
             return ChangeCase(c, toUpper: false);
         }
 
-        public virtual string ToLower(string str)
+        public string ToLower(string str)
         {
             if (str == null)
             {
@@ -534,7 +534,7 @@ namespace System.Globalization
         /// Converts the character or string to upper case.  Certain locales
         /// have different casing semantics from the file systems in Win32.
         /// </summary>
-        public virtual char ToUpper(char c)
+        public char ToUpper(char c)
         {
             if (GlobalizationMode.Invariant || (IsAscii(c) && IsAsciiCasingSameAsInvariant))
             {
@@ -544,7 +544,7 @@ namespace System.Globalization
             return ChangeCase(c, toUpper: true);
         }
 
-        public virtual string ToUpper(string str)
+        public string ToUpper(string str)
         {
             if (str == null)
             {
index 32f4161..ab211ec 100644 (file)
@@ -181,7 +181,7 @@ namespace System
             {
                 throw new ArgumentNullException(nameof(obj));
             }
-            return _compareInfo.GetHashCodeOfString(obj, _options);
+            return _compareInfo.GetHashCode(obj, _options);
         }
 
         // Equals method for the comparer itself.
index 894719b..9e91c7f 100644 (file)
@@ -4513,18 +4513,18 @@ namespace System.Globalization
         public override System.DateTime MinSupportedDateTime { get { throw null; } }
         public override int GetEra(System.DateTime time) { throw null; }
     }
-    public partial class CompareInfo : System.Runtime.Serialization.IDeserializationCallback
+    public sealed partial class CompareInfo : System.Runtime.Serialization.IDeserializationCallback
     {
         internal CompareInfo() { }
         public int LCID { get { throw null; } }
-        public virtual string Name { get { throw null; } }
+        public string Name { get { throw null; } }
         public System.Globalization.SortVersion Version { get { throw null; } }
-        public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2) { throw null; }
-        public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int Compare(string? string1, int offset1, string? string2, int offset2) { throw null; }
-        public virtual int Compare(string? string1, int offset1, string? string2, int offset2, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int Compare(string? string1, string? string2) { throw null; }
-        public virtual int Compare(string? string1, string? string2, System.Globalization.CompareOptions options) { throw null; }
+        public int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2) { throw null; }
+        public int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2, System.Globalization.CompareOptions options) { throw null; }
+        public int Compare(string? string1, int offset1, string? string2, int offset2) { throw null; }
+        public int Compare(string? string1, int offset1, string? string2, int offset2, System.Globalization.CompareOptions options) { throw null; }
+        public int Compare(string? string1, string? string2) { throw null; }
+        public int Compare(string? string1, string? string2, System.Globalization.CompareOptions options) { throw null; }
         public override bool Equals(object? value) { throw null; }
         public static System.Globalization.CompareInfo GetCompareInfo(int culture) { throw null; }
         public static System.Globalization.CompareInfo GetCompareInfo(int culture, System.Reflection.Assembly assembly) { throw null; }
@@ -4532,39 +4532,39 @@ namespace System.Globalization
         public static System.Globalization.CompareInfo GetCompareInfo(string name, System.Reflection.Assembly assembly) { throw null; }
         public override int GetHashCode() { throw null; }
         public int GetHashCode(System.ReadOnlySpan<char> source, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int GetHashCode(string source, System.Globalization.CompareOptions options) { throw null; }
-        public virtual System.Globalization.SortKey GetSortKey(string source) { throw null; }
-        public virtual System.Globalization.SortKey GetSortKey(string source, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int IndexOf(string source, char value) { throw null; }
-        public virtual int IndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int IndexOf(string source, char value, int startIndex) { throw null; }
-        public virtual int IndexOf(string source, char value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int IndexOf(string source, char value, int startIndex, int count) { throw null; }
-        public virtual int IndexOf(string source, char value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int IndexOf(string source, string value) { throw null; }
-        public virtual int IndexOf(string source, string value, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int IndexOf(string source, string value, int startIndex) { throw null; }
-        public virtual int IndexOf(string source, string value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int IndexOf(string source, string value, int startIndex, int count) { throw null; }
-        public virtual int IndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
-        public virtual bool IsPrefix(string source, string prefix) { throw null; }
-        public virtual bool IsPrefix(string source, string prefix, System.Globalization.CompareOptions options) { throw null; }
+        public int GetHashCode(string source, System.Globalization.CompareOptions options) { throw null; }
+        public System.Globalization.SortKey GetSortKey(string source) { throw null; }
+        public System.Globalization.SortKey GetSortKey(string source, System.Globalization.CompareOptions options) { throw null; }
+        public int IndexOf(string source, char value) { throw null; }
+        public int IndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; }
+        public int IndexOf(string source, char value, int startIndex) { throw null; }
+        public int IndexOf(string source, char value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
+        public int IndexOf(string source, char value, int startIndex, int count) { throw null; }
+        public int IndexOf(string source, char value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
+        public int IndexOf(string source, string value) { throw null; }
+        public int IndexOf(string source, string value, System.Globalization.CompareOptions options) { throw null; }
+        public int IndexOf(string source, string value, int startIndex) { throw null; }
+        public int IndexOf(string source, string value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
+        public int IndexOf(string source, string value, int startIndex, int count) { throw null; }
+        public int IndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
+        public bool IsPrefix(string source, string prefix) { throw null; }
+        public bool IsPrefix(string source, string prefix, System.Globalization.CompareOptions options) { throw null; }
         public static bool IsSortable(char ch) { throw null; }
         public static bool IsSortable(string text) { throw null; }
-        public virtual bool IsSuffix(string source, string suffix) { throw null; }
-        public virtual bool IsSuffix(string source, string suffix, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int LastIndexOf(string source, char value) { throw null; }
-        public virtual int LastIndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int LastIndexOf(string source, char value, int startIndex) { throw null; }
-        public virtual int LastIndexOf(string source, char value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int LastIndexOf(string source, char value, int startIndex, int count) { throw null; }
-        public virtual int LastIndexOf(string source, char value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int LastIndexOf(string source, string value) { throw null; }
-        public virtual int LastIndexOf(string source, string value, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int LastIndexOf(string source, string value, int startIndex) { throw null; }
-        public virtual int LastIndexOf(string source, string value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
-        public virtual int LastIndexOf(string source, string value, int startIndex, int count) { throw null; }
-        public virtual int LastIndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
+        public bool IsSuffix(string source, string suffix) { throw null; }
+        public bool IsSuffix(string source, string suffix, System.Globalization.CompareOptions options) { throw null; }
+        public int LastIndexOf(string source, char value) { throw null; }
+        public int LastIndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; }
+        public int LastIndexOf(string source, char value, int startIndex) { throw null; }
+        public int LastIndexOf(string source, char value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
+        public int LastIndexOf(string source, char value, int startIndex, int count) { throw null; }
+        public int LastIndexOf(string source, char value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
+        public int LastIndexOf(string source, string value) { throw null; }
+        public int LastIndexOf(string source, string value, System.Globalization.CompareOptions options) { throw null; }
+        public int LastIndexOf(string source, string value, int startIndex) { throw null; }
+        public int LastIndexOf(string source, string value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
+        public int LastIndexOf(string source, string value, int startIndex, int count) { throw null; }
+        public int LastIndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
         void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
         public override string ToString() { throw null; }
     }
@@ -5168,29 +5168,29 @@ namespace System.Globalization
         public bool MoveNext() { throw null; }
         public void Reset() { }
     }
-    public partial class TextInfo : System.ICloneable, System.Runtime.Serialization.IDeserializationCallback
+    public sealed partial class TextInfo : System.ICloneable, System.Runtime.Serialization.IDeserializationCallback
     {
         internal TextInfo() { }
-        public virtual int ANSICodePage { get { throw null; } }
+        public int ANSICodePage { get { throw null; } }
         public string CultureName { get { throw null; } }
-        public virtual int EBCDICCodePage { get { throw null; } }
+        public int EBCDICCodePage { get { throw null; } }
         public bool IsReadOnly { get { throw null; } }
         public bool IsRightToLeft { get { throw null; } }
         public int LCID { get { throw null; } }
-        public virtual string ListSeparator { get { throw null; } set { } }
-        public virtual int MacCodePage { get { throw null; } }
-        public virtual int OEMCodePage { get { throw null; } }
-        public virtual object Clone() { throw null; }
+        public string ListSeparator { get { throw null; } set { } }
+        public int MacCodePage { get { throw null; } }
+        public int OEMCodePage { get { throw null; } }
+        public object Clone() { throw null; }
         public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static System.Globalization.TextInfo ReadOnly(System.Globalization.TextInfo textInfo) { throw null; }
         void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
-        public virtual char ToLower(char c) { throw null; }
-        public virtual string ToLower(string str) { throw null; }
+        public char ToLower(char c) { throw null; }
+        public string ToLower(string str) { throw null; }
         public override string ToString() { throw null; }
         public string ToTitleCase(string str) { throw null; }
-        public virtual char ToUpper(char c) { throw null; }
-        public virtual string ToUpper(string str) { throw null; }
+        public char ToUpper(char c) { throw null; }
+        public string ToUpper(string str) { throw null; }
     }
     public partial class ThaiBuddhistCalendar : System.Globalization.Calendar
     {