Управляющие последовательности символов Юникода

Управляющая последовательность символов Юникода представляет собой символ Юникода. Управляющие последовательности символов Юникода обрабатываются в идентификаторах (§2.4.2), символьных литералах (§2.4.4.4) и правильных строковых литералах (§2.4.4.5). Управляющая последовательность символов Юникода не обрабатывается в других местах (например, для образования оператора, знака пунктуации или ключевого слова).

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

Управляющая последовательность Юникода (escape-последовательность Юникода) представляет собой один символ Юникода, образованный шестнадцатеричным числом, следующим за символами "\u" или "\U". Поскольку в C# используется 16-разрядная кодировка элементов кода Юникода в символьных и строковых значениях, символ Юникода в диапазоне от U+10000 до U+10FFFF запрещен в строковом литерале и представляется с помощью суррогатной пары Юникода в строковом литерале. Символы Юникода с элементами кода выше 0x10FFFF не поддерживаются.

Многократные трансляции не выполняются. Например, строковый литерал "\u005Cu005C" эквивалентен "\u005C", а не "\". Значение Юникода \u005C является символом "\".

Пример:

class Class1
{
static void Test(bool \u0066) {
char c = '\u0066';
if (\u0066)
System.Console.WriteLine(c.ToString());
}
}

показано несколько использований \u0066, escape-последовательности для буквы "f". Эта программа эквивалентна следующей:

class Class1
{
static void Test(bool f) {
char c = 'f';
if (f)
System.Console.WriteLine(c.ToString());
}
}

Идентификаторы

Правила для идентификаторов в этом разделе точно соответствуют правилам, рекомендованным в дополнении 31 к стандарту Юникода, за исключением следующего: знак подчеркивания разрешен в качестве начального символа (что традиционно для языка программирования C), escape-последовательности Юникода разрешены в идентификаторах, а символ "@" разрешен в качестве префикса, чтобы можно было использовать ключевые слова в качестве идентификаторов.

identifier:
available-identifier
@ identifier-or-keyword

available-identifier:
An identifier-or-keyword that is not a keyword

identifier-or-keyword:
identifier-start-character identifier-part-charactersopt

identifier-start-character:
letter-character
_ (the underscore character U+005F)

identifier-part-characters:
identifier-part-character
identifier-part-characters identifier-part-character

identifier-part-character:
letter-character
decimal-digit-character
connecting-character
combining-character
formatting-character

letter-character:
A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl
A unicode-escape-sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl

combining-character:
A Unicode character of classes Mn or Mc
A unicode-escape-sequence representing a character of classes Mn or Mc

decimal-digit-character:
A Unicode character of the class Nd
A unicode-escape-sequence representing a character of the class Nd

connecting-character:
A Unicode character of the class Pc
A unicode-escape-sequence representing a character of the class Pc

formatting-character:
A Unicode character of the class Cf
A unicode-escape-sequence representing a character of the class Cf

Дополнительные сведения об упомянутых выше классах символов Юникода см. в документе Стандарт Юникода, версия 3.0, раздел 4.5.

Примеры допустимых идентификаторов: "identifier1", "_identifier2" и "@if".

Идентификатор в соответствующей программе должен быть в каноническом формате, определенном формой нормализации C Юникода, как определено в дополнении 15 к стандарту Юникода. Поведение при обнаружении идентификатора не в форме нормализации C определяется реализацией, однако диагностика при этом не требуется.

Префикс "@" позволяет использовать ключевые слова в качестве идентификаторов, что полезно при взаимодействии с другими языками программирования. Символ @ фактически не является частью идентификатора, так что этот идентификатор может отображаться в других языках в виде обычного идентификатора, без префикса. Идентификатор с префиксом @ называется буквальным идентификатором. Использование префикса @ для идентификаторов, не являющихся ключевыми словами, разрешено, но настоятельно не рекомендуется со стилистической точки зрения.

Пример:

class @class
{
public static void @static(bool @bool) {
if (@bool)
System.Console.WriteLine("true");
else
System.Console.WriteLine("false");
}
}

class Class1
{
static void M() {
cl\u0061ss.st\u0061tic(true);
}
}

определяется класс class со статическим методом с именем static, который принимает параметр с именем bool. Обратите внимание, что, поскольку управляющие последовательности Юникода не разрешены в ключевых словах, лексема "cl\u0061ss" является идентификатором, причем тем же идентификатором, что и "@class".

Два идентификатора считаются одинаковыми, если они идентичны после применения следующих преобразований в таком порядке:

· если используется префикс "@", он удаляется;

· каждая последовательность управляющих символов Юникода преобразуется в соответствующий символ Юникода;

· все символы управления форматом удаляются.

Идентификаторы, содержащие два последовательных символа подчеркивания (U+005F), зарезервированы для использования в реализации. Например, реализация может предоставлять расширенные ключевые слова, начинающиеся с двух символов подчеркивания.

Ключевые слова

Ключевое слово — это подобная идентификатору зарезервированная последовательность символов. Ключевое слово нельзя использовать в качестве идентификатора за исключением его использования с префиксом @.

keyword: one of
abstract as base bool break
byte case catch char checked
class const continue decimal default
delegate do double else enum
event explicit extern false finally
fixed float for foreach goto
if implicit in int interface
internal is lock long namespace
new null object operator out
override params private protected public
readonly ref return sbyte sealed
short sizeof stackalloc static string
struct switch this throw true
try typeof uint ulong unchecked
unsafe ushort using virtual void
volatile while

В некоторых положениях грамматики особые идентификаторы имеют особое значение, но не являются ключевыми словами. Такие идентификаторы иногда называются «контекстными ключевыми словами». Например, в объявлении свойства идентификаторы get и set имеют особое значение (§10.7.2). Идентификатор, отличный от get или set, никогда не разрешается в этих положениях, поэтому такое использование не приводит к конфликту с использованием этих слов в качестве идентификаторов. В других случаях, как, например, с идентификатором var в объявлениях с неявно типизированной локальной переменной (§8.5.1), контекстное ключевое слово может конфликтовать с объявленными именами. Тогда объявленное имя получает приоритет над использованием идентификатора в качестве контекстного ключевого слова.

Литералы

Литерал — это представление значения в исходном коде.

literal:
boolean-literal
integer-literal
real-literal
character-literal
string-literal
null-literal

Логические литералы

Логический литерал может иметь два значения: true и false.

boolean-literal:
true
false

Логический литерал имеет тип bool.

Целочисленные литералы

Целочисленные литералы используются для записи значений типа int, uint, long или ulong. Целочисленные литералы имеют две возможных формы: десятичную и шестнадцатеричную.

integer-literal:
decimal-integer-literal
hexadecimal-integer-literal

decimal-integer-literal:
decimal-digits integer-type-suffixopt

decimal-digits:
decimal-digit
decimal-digits decimal-digit

decimal-digit: one of
0 1 2 3 4 5 6 7 8 9

integer-type-suffix: one of
U u L l UL Ul uL ul LU Lu lU lu

hexadecimal-integer-literal:
0x hex-digits integer-type-suffixopt
0X hex-digits integer-type-suffixopt

hex-digits:
hex-digit
hex-digits hex-digit

hex-digit: one of
0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f

Тип целочисленного литерала определяется следующим образом:

· если литерал без суффикса, его тип — первый из этих типов, в которых его значение может быть представлено: int, uint, long, ulong;

· если литерал имеет суффикс U или u, он относится к первому из этих типов, в которых его значение может быть представлено как uint или ulong;

· если литерал с суффиксом L или l, его тип — первый из этих типов, в которых его значение может быть представлено: long и ulong;

· если литерал имеет суффикс UL, Ul, uL, ul, LU, Lu, lU или lu, он относится к типу ulong.

Если представленное целочисленным литералом значение находится за пределами диапазона типа ulong, выдается ошибка времени компиляции.

Рекомендуется использовать L вместо l при записи литералов типа long, так как букву l легко спутать с цифрой 1.

Для записи минимально возможных значений int и long в виде десятичных целочисленных литералов существуют следующие два правила:

· если десятичный целочисленный литерал со значением 2147483648 (231) и без суффикса целочисленного типа появляется в качестве лексемы, непосредственно следующей за лексемой оператора унарного минуса (§7.7.2), результатом является константа типа int со значением −2147483648 (−231). Во всех других ситуациях десятичный целочисленный литерал относится к типу uint.

· если десятичный целочисленный литерал со значением 9223372036854775808 (263) и без суффикса целочисленного типа или с суффиксом целочисленного типа L или l появляется в качестве лексемы, непосредственно следующей за лексемой оператора унарного минуса (§7.7.2), результатом является константа типа long со значением −9223372036854775808 (−263). Во всех других ситуациях десятичный целочисленный литерал имеет тип ulong;

Действительные литералы

Действительные литералы используются для записи значений типа float, double или decimal.

real-literal:
decimal-digits . decimal-digits exponent-partopt real-type-suffixopt
. decimal-digits exponent-partopt real-type-suffixopt
decimal-digits exponent-part real-type-suffixopt
decimal-digits real-type-suffix

exponent-part:
e signopt decimal-digits
E signopt decimal-digits

sign: one of
+ -

real-type-suffix: one of
F f D d M m

Если суффикс действительного типа не указан, типом действительного литерала является double. Иначе суффикс действительного типа определяет тип действительного литерала следующим образом:

· Действительный литерал с суффиксом F или f относится к типу float. Например, каждый из литералов 1f, 1.5f, 1e10f и 123.456F относится к типу float.

· действительный литерал с суффиксом D или d имеет тип double. Например, литералы 1d, 1.5d, 1e10d и 123.456D все имеют тип double;

· действительный литерал с суффиксом M или m имеет тип decimal. Например, литералы 1m, 1.5m, 1e10m и 123.456M все имеют тип decimal; Этот литерал преобразуется в значение типа decimal, принимая его точное значение и при необходимости округляя до ближайшего могущего быть представленным значения с помощью банковского округления (§4.1.7). Любой масштаб, видимый в литерале, сохраняется, если только значение не округляется и не равно нулю (в этом последнем случае знак и масштаб будут равны 0). Следовательно, синтаксический разбор литерала 2.900m создаст десятичное значение со знаком 0, коэффициентом 2900 и масштабом 3.

Если указанный литерал не удается представить в предписанном типе, выдается ошибка времени компиляции.

Значение действительного литерала с типом float или double определяется с помощью режима "округления до ближайшего" по стандарту IEEE.

Обратите внимание, что в действительном литерале всегда требуются десятичные цифры после десятичной точки. Например, 1.3F — это действительный литерал, а 1.F — нет.

Символьные литералы

Символьный литерал представляет один символ и обычно состоит из символа в кавычках, например 'a'.

character-literal:
' character '

character:
single-character
simple-escape-sequence
hexadecimal-escape-sequence
unicode-escape-sequence

single-character:
Any character except ' (U+0027), \ (U+005C), and new-line-character

simple-escape-sequence: one of
\' \" \\ \0 \a \b \f \n \r \t \v

hexadecimal-escape-sequence:
\x hex-digit hex-digitopt hex-digitopt hex-digitopt

Символ, следующий за обратной косой чертой (\) в символе, должен быть одним из следующих: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. Иначе возникает ошибка времени компиляции.

Шестнадцатеричная escape-последовательность представляет собой один символ Юникода со значением, образованным шестнадцатеричным числом, следующим за \x.

Если значение, представленное символьным литералом, больше U+FFFF, вызывается ошибка времени компиляции.

Управляющая последовательность символов Юникода (§2.4.1) в символьном литерале должна быть в диапазоне от U+0000 до U+FFFF.

Простая управляющая последовательность представляет собой кодировку символа Юникода, как показано в следующей таблице.

Escape-последовательность Имя символа Кодировка Юникода
\' Одинарная кавычка 0x0027
\" Двойные кавычки 0x0022
\\ Обратная косая черта 0x005C
\0 Null 0x0000
\a Предупреждение 0x0007
\b Возврат 0x0008
\f Перевод страницы 0x000C
\n Новая строка 0x000A
\r Возврат каретки 0x000D
\t Горизонтальная табуляция 0x0009
\v Вертикальная табуляция 0x000B

Символьный литерал относится к типу char.

Строковые литералы

В C# поддерживается две формы строковых литералов: правильные строковые литералы и буквальные строковые литералы.

Правильный строковый литерал состоит из нуля или более символов, заключенных в двойные кавычки, например "hello", и может включать как простые управляющие последовательности (например \t для символа табуляции), так и шестнадцатеричные escape-последовательности и escape-последовательности Юникода.

Буквальный строковый литерал состоит из символа @ с последующими символом двойных кавычек, нулем или более символов и закрывающим символом двойных кавычек. Простым примером является @"hello". В буквальном строковом литерале символы между разделителями интерпретируются буквально, единственным исключением является управляющая последовательность кавычки. В частности, простые управляющие последовательности, шестнадцатеричные escape-последовательности и escape-последовательности Юникода не обрабатываются в буквальных строковых литералах. Буквальный строковый литерал может занимать несколько строк.

string-literal:
regular-string-literal
verbatim-string-literal

regular-string-literal:
" regular-string-literal-charactersopt "

regular-string-literal-characters:
regular-string-literal-character
regular-string-literal-characters regular-string-literal-character

regular-string-literal-character:
single-regular-string-literal-character
simple-escape-sequence
hexadecimal-escape-sequence
unicode-escape-sequence

single-regular-string-literal-character:
Any character except " (U+0022), \ (U+005C), and new-line-character

verbatim-string-literal:
@" verbatim-string-literal-charactersopt "

verbatim-string-literal-characters:
verbatim-string-literal-character
verbatim-string-literal-characters verbatim-string-literal-character

verbatim-string-literal-character:
single-verbatim-string-literal-character
quote-escape-sequence

single-verbatim-string-literal-character:
Any character except "

quote-escape-sequence:
""

Символ, следующий за символом обратной косой черты (\) в символе правильного строкового литерала, должен быть одним из следующих символов: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. Иначе возникает ошибка времени компиляции.

Пример:

string a = "hello, world"; // hello, world
string b = @"hello, world"; // hello, world

string c = "hello \t world"; // hello world
string d = @"hello \t world"; // hello \t world

string e = "Joe said \"Hello\" to me"; // Joe said "Hello" to me
string f = @"Joe said ""Hello"" to me"; // Joe said "Hello" to me

string g = "\\\\server\\share\\file.txt"; // \\server\share\file.txt
string h = @"\\server\share\file.txt"; // \\server\share\file.txt

string i = "one\r\ntwo\r\nthree";
string j = @"one
two
three";

показаны разнообразные строковые литералы. Последний строковый литерал j является буквальным строковым литералом, занимающим несколько строк. Символы между кавычками, включая пробелы, например символы новой строки, сохраняются буквально.

Поскольку в шестнадцатеричной escape-последовательности может быть переменное число шестнадцатеричных цифр, строковый литерал "\x123" содержит один символ с шестнадцатеричным значением 123. Чтобы создать строку, содержащую символ с шестнадцатеричным значением 12 и с последующим символом 3, можно написать "\x00123" или "\x12" + "3".

Строковый литерал имеет тип string.

Результатом каждого строкового литерала не обязательно является новый экземпляр строки. Если два или более строковых литерала, эквивалентных согласно оператору равенства строк (§7.10.7), появляются в одной программе, эти строковые литералы ссылаются на один и тот же экземпляр строки. Например, программа

class Test
{
static void Main() {
object a = "hello";
object b = "hello";
System.Console.WriteLine(a == b);
}
}

выведет True, так как эти два литерала ссылаются на один и тот же экземпляр строки.

Литерал null

null-literal:
null

Литерал NULL может быть неявно преобразован в ссылочный тип или обнуляемый тип.

Наши рекомендации