.NET и юникод
От: _NN_ www.nemerleweb.com
Дата: 28.01.24 11:34
Оценка: 18 (3)
Как считаете, какой должен быть вывод этой программы ?

Проверьте себя .NET Framework, .NET 8.

using System;
                    
public class Program
{
    public static void Main()
    {
        string one = 1.ToString();
        bool starts = one.StartsWith("\U00011052"); // 𑁒
        bool equals_inv = one.Equals("\U00011052", System.StringComparison.InvariantCulture);
        bool equals = one.Equals("\U00011052");
        System.Console.WriteLine(starts);
        System.Console.WriteLine(equals_inv);
        System.Console.WriteLine(equals);
    }
}


  Для нетерпеливых
https://github.com/dotnet/csharplang/discussions/7876
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: .NET и юникод
От: m2user  
Дата: 28.01.24 19:31
Оценка:
Поведение конечно неожиданно. Но что ты хотел получить сравнивая строки без указания культуры
MS везде (в частности в code anlysis) пишет о том, что так делать не стоит.
Хотя бы потому, что если культура не указана, то берётся текущая локаль потока выполнения, которая в свою очередь зависит от локали процесса/пользователя/машины.
И может быть совсем не такой, какую ожидает разработчик.

Дополню: CA rules по глобализации: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/globalization-warnings

Best practices for comparing strings in .NET

Comparisons that use current culture semantics are the default for the following methods:

String.Compare overloads that don't include a StringComparison parameter.
String.CompareTo overloads.
The default String.StartsWith(String) method, and the String.StartsWith(String, Boolean, CultureInfo) method with a nullCultureInfo parameter.
The default String.EndsWith(String) method, and the String.EndsWith(String, Boolean, CultureInfo) method with a nullCultureInfo parameter.
String.IndexOf overloads that accept a String as a search parameter and that don't have a StringComparison parameter.
String.LastIndexOf overloads that accept a String as a search parameter and that don't have a StringComparison parameter.


Ordinal semantics are the default for String.Equals overloads that don't include a StringComparison argument (including the equality operator).


Т.е. результат String.StartsWith зависит от локали потока выполнения, и только по коду однозначно ответить нельзя.
Отредактировано 28.01.2024 21:20 m2user . Предыдущая версия .
Re[2]: .NET и юникод
От: _NN_ www.nemerleweb.com
Дата: 29.01.24 09:19
Оценка: +1
Здравствуйте, m2user, Вы писали:

M>Поведение конечно неожиданно. Но что ты хотел получить сравнивая строки без указания культуры


В тои и дело что даже указывая культуру результат немного другой в .NET 8.

using System;
                    
public class Program
{
    public static void Main()
    {
        string one = 1.ToString();
        bool starts_inv = one.StartsWith("\U00011052", System.StringComparison.InvariantCulture);
        bool starts_ord = one.StartsWith("\U00011052", System.StringComparison.Ordinal);
        bool starts = one.StartsWith("\U00011052"); // 𑁒
        bool equals_inv = one.Equals("\U00011052", System.StringComparison.InvariantCulture);
        bool equals_ord = one.Equals("\U00011052", System.StringComparison.Ordinal);
        bool equals = one.Equals("\U00011052");
        System.Console.WriteLine(starts_inv);
        System.Console.WriteLine(starts_ord);
        System.Console.WriteLine(starts);
        System.Console.WriteLine(equals_inv);
        System.Console.WriteLine(equals_ord);
        System.Console.WriteLine(equals);
    }
}


Результат:
  .NET Framework
False
False
False
False
False
False


  .NET 8
True
False
True
True
False
False
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: .NET и юникод
От: m2user  
Дата: 29.01.24 10:19
Оценка: 14 (1)
_NN>В тои и дело что даже указывая культуру результат немного другой в .NET 8.

Я полагаю, это с этим связано: Behavior changes when comparing strings on .NET 5+

Чтобы проверить, работает ли переключение на старую библиотеку (NLS), нужна машинка с MS Windows.

System.Globalization.UseNls:
false — Use ICU globalization APIs
true — Use NLS globalization APIs

Re[4]: .NET и юникод
От: _NN_ www.nemerleweb.com
Дата: 30.01.24 07:48
Оценка: +1
Здравствуйте, m2user, Вы писали:

Тут ещё стоит отметить , что в Equals в отличии от других методов сравнение по умолчанию использует Ordinal.
С точки зрения производительности это конечно хорошо, но может давать неожиданное поведение.
Т.е. строки могут быть разными по Equals но StartsWith с культурой по умолчанию либо инвариантной вернёт истину.
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.