Что такое `\U`?

Встретил вот такую задачу:

string str1 = "\U0010FADE";
string str2 = "\U0000FADE";

Console.WriteLine(str1.Length);
Console.WriteLine(str2.Length);

Как оказалось, выводится 2 и 1. Что тут вообще происходит?

Я знаю только строчную \u, за которой должны следовать 4 шестнадцатеричных цифры.

В MSDN для char \U не перечисляется, что логично - результат явно не char.

Для строк - есть упоминание, но всё равно непонятно:

The escape code \udddd (where dddd is a four-digit number) represents the Unicode character U+dddd. Eight-digit Unicode escape codes are also recognized: \Udddddddd.

В другом месте говорится, что они нужны для формирования суррогатных пар, но тоже без дальнейших пояснений:

\Uxxxxxxxx - Unicode escape sequence for character with hex value xxxxxxxx (for generating surrogates)

Так что делает \U и почему во втором строке получилась не суррогатная пара, а только один символ?

Попробовал запустить на ideone, но что-то выведенные символы имеют не те коды, которые указаны в исходниках. Хотя это может быть косяком самого ideone.


Ответы (1 шт):

Автор решения: MSDN.WhiteKnight

Информация в документации абсолютно правильна. Синтаксис \Udddddddd просто включает в строковую константу символ Юникод с кодом dddddddd. Этот символ может быть суррогатной парой и занимать две кодовые единицы UTF-16, но может быть также и обычным символом, занимающим одну кодовую единицу.

ECMA-334

7.4.2 Unicode character escape sequences

A Unicode escape sequence represents a Unicode code point. Unicode escape sequences are processed in identifiers (§7.4.3), character literals (§7.4.5.5), and regular string literals (§7.4.5.6). A Unicode escape sequence is not processed in any other location (for example, to form an operator, punctuator, or keyword).

unicode-escape-sequence:: 

\u hex-digit hex-digit hex-digit hex-digit 
\U hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit 

A Unicode character escape sequence represents the single Unicode code point formed by the hexadecimal number following the “\u” or “\U” characters. Since C# uses a 16-bit encoding of Unicode code points in character and string values, a Unicode code point in the range U+10000 to U+10FFFF is represented using two Unicode surrogate code units. Unicode code points above U+FFFF are not permitted in character literals. Unicode code points above U+10FFFF are invalid and are not supported.

В первом случае значение кодовой позиции больше U+10000, поэтому оно представлено двумя кодовыми единицами. Во втором случае - меньше, поэтому одной.

Другими словами, запись \U0000FADE эквивалентна \uFADE, а не \u0000\uFADE, как может показаться на первый взгляд (последняя действительно состоит из двух кодовых единиц).

→ Ссылка