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

Я тут Си-шарп начал учить, удивляюсь всему, как ребёнок, с первых же страниц. Идентификаторы (42.74КиБ) Обратите внимание на строку 9, тут любопытно, я встречал языки, где в качестве имён переменных можно использовать символы Юникода (тот же ПХП), а тут, мало того, можно писать юникодные символы с использованием слеш-ю-нотации!

Например, у меня, в качестве имени переменной, используется символ «усмехающееся кошачье лицо со смешинками в глазах» (не всем видно будет — 😸). Со вторым идентификатором ещё интереснее.

Если вам нужно использовать в качестве идентификатора зарезервированное слово (ну вот надо, а максимально подходящее английское слово является зарезервированным), можно предварить его «собачкой» и в таком виде использовать (см. строку 10).

Программа выше компилируется и выполняется без ошибок.

А вот вещь по которой я скучал: фигурные скобки создают локальную область видимости (как в Перле), правда я не могу определить переменную в этом блоке, которая уже есть в локальном блоке выше, причём только до замыкания, удивительное правило.

Ну да ладно, в общем, вот такой код не скомпилируется, будет ошибка в последней строке, сообщающая об отсутствие переменной @string:
{
	string @string = @"string ""string""";
	Console.WriteLine (@string.Insert (1, "tt"));
}

Console.WriteLine (@string); // ошибка!
Вещь, с которой не ожидал столкнуться — автоматическое приведение типов. Я как-то был уверен (о Си-шарпе я только слышал, но ничего определённого не знал), что тут будет как в Гоу или Си — нужно преобразовывать переменные к какому-то единому типу, а уже потом что-то с ним делать. Оказалось, ничего подобного:
byte байтраз = 3, байтдва = 5;

// строка кода ниже выведет System.Int32 (а не System.Byte, как я ожидал)
// арифметические операции определены только для типов int и больше,
// поэтому произойдёт преобразование типов
Console.WriteLine ((байтраз + байтдва).GetType());

Console.WriteLine ("Первый байт равен: " + байтраз); // строки спокойно складываются с числами
Ещё интересная вещь — отключение проверки переполнения (в нормальной ситуации вызовется исключение), видимо для совместимости с сишным поведением:
int int1, int2;
unchecked {
	int1 = int2 = System.Int32.MaxValue;
	int1 += int2;
}
Console.WriteLine (int1); // выведет -2
22 мая 2013 08:49

Raiden (инкогнито)
22 мая 2013, 12:01

Console.WriteLine ("Первый байт равен: " + байтраз); // строки спокойно складываются с числами
У любого объекта есть виртуальная функция ToString(), которая и вызывается неявно при конкатенации строк.

Raiden (инкогнито)
22 мая 2013, 12:09

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

А по поводу странной области видимости, так это сделано для того, чтобы программист не допускал глупых ошибок и не путал переменные.

Евгений Степанищев (bolknote.ru)
22 мая 2013, 12:10, ответ предназначен Raiden

Как в Джаваскрипте? Интересно. Я посмотрел, даже пустой объект что-то возвращает:
var @object = new {};
Console.WriteLine ("" + @object); // вернёт {}

Евгений Степанищев (bolknote.ru)
22 мая 2013, 12:17, ответ предназначен Raiden

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

Raiden (инкогнито)
22 мая 2013, 13:13

Как в Джаваскрипте? Интересно. Я посмотрел, даже пустой объект что-то возвращает
Да, все объекты (в том числе стековые, типа int и bool) наследуются от объекта object. А этот объект имеет набор виртуальных функций: ToString(), GetHash(), GetType() и Equals(). Другими словами эти функции есть у любого объекта.

Raiden (инкогнито)
22 мая 2013, 13:51

Это вряд ли можно считать правилом. При приведении типов может кончиться память, будет исключение.
Не буду утверждать, но что-то мне подсказывает, что во время приведения типов переполнении памяти быть не может. Когда-то очень давно читал статью на эту тему, но, к сожалению, найти уже не могу. По-моему логика была примерно в том, что на уровне MSIL сначала выделяется память под переменную, а потом происходит приведение. Причем сама операция приведения проходит не в стеке приложения, потому к StackOverflow привести не может.
Хотя тут могу ошибаться.

А говоря о правиле приведения, я имел ввиду именно исключения при выходе за диапазон значений. Т.е. типы с меньшим диапазоном приводятся к большим без явного объявления.

DuMOHsmol (anothersite.ru)
22 мая 2013, 15:58

Насчет русских переменных, можно ещё делать вот так:

Евгений Степанищев (bolknote.ru)
22 мая 2013, 16:17, ответ предназначен DuMOHsmol (anothersite.ru):

Тоже забавно :) Наверное, предпроцессором можно и ключевые слова заменить?

PastorGL (инкогнито)
22 мая 2013, 18:32, ответ предназначен Евгений Степанищев (bolknote.ru):

Наверное, предпроцессором можно и ключевые слова заменить?
Нет, нельзя. Препроцессора в шарпе как такового нет. http://msdn.microsoft.com/en-us/library/ed8yd1ha(v=vs.110).aspx

Андрей (инкогнито)
23 мая 2013, 06:58

тут будет как в Гоу или Си
Когда си стал strong typed то? :)

dinoelq (инкогнито)
23 мая 2013, 07:23

Это всё фигня по сравнению с linq :) Там такоооой простор для творчества

Евгений Степанищев (bolknote.ru)
23 мая 2013, 07:59, ответ предназначен Андрей

Когда Си стал строго типизированным-то? :)
С Си я неточно выразился, скорее моё недоумение касалось вот такой вещи:
int main() {
char *str = "Hello";
int digit = 1;
printf("%s", str + digit);
}

Евгений Степанищев (bolknote.ru)
23 мая 2013, 07:59, ответ предназначен dinoelq

Это всё фигня по сравнению с linq :) Там такоооой простор для творчества
Разве это не те же генераторы с itertools из Пайтона? В Пайтоне это компактнее и красивее.

sfersox (инкогнито)
23 мая 2013, 12:11

А у меня не получилось объявить переменную int \uD83D\uDE38. Пишет непредвиденный знак \uD83D. Почему так? А вот с собачкой в имени переменной все хорошо. Юзаю Visual C# 2010.

Евгений Степанищев (bolknote.ru)
23 мая 2013, 12:32, ответ предназначен sfersox

А у меня не получилось объявить переменную int \uD83D\uDE38
Должно работать, см. пункт 2.4.1 в руководстве (http://go.microsoft.com/fwlink/?LinkId=199552).

sfersox (инкогнито)
23 мая 2013, 15:24, ответ предназначен Евгений Степанищев (bolknote.ru):

Хм, получилось. Видимо в примере не корректный юникод используется.

Евгений Степанищев (bolknote.ru)
23 мая 2013, 15:33, ответ предназначен sfersox

В моём пример? У меня ж компилируется. Правда, это не Visual C# 2010, да и символ из свежего стандарта Юникода.

sfersox (инкогнито)
23 мая 2013, 16:13, ответ предназначен Евгений Степанищев (bolknote.ru):

Ну да, именно из примера код не проходит.Может это зависит от системы?

Евгений Степанищев (bolknote.ru)
23 мая 2013, 16:32, ответ предназначен sfersox

Не удивлюсь. В Винде традиционно всё плохо с Юникодом.

zg (zg.livejournal.com)
23 мая 2013, 21:14

а где традиционно хорошо?

Евгений Степанищев (bolknote.ru)
23 мая 2013, 21:58, ответ предназначен zg (zg.livejournal.com):

На «Маке».

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)