Идентификаторы в C#
Я тут Си-шарп начал учить, удивляюсь всему, как ребёнок, с первых же страниц.
Обратите внимание на строку 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
У любого объекта есть виртуальная функция ToString(), которая и вызывается неявно при конкатенации строк.
Если приведение типов безопасное, т. е. не вызовет исключений ни при каких обстоятельствах, то оно автоматическое. А вот опасные приведения только явные.
А по поводу странной области видимости, так это сделано для того, чтобы программист не допускал глупых ошибок и не путал переменные.
Комментарий для Raiden:
Как в Джаваскрипте? Интересно. Я посмотрел, даже пустой объект что-то возвращает:
Комментарий для Raiden:
Это вряд ли можно считать правилом. При приведении типов может кончиться память, будет исключение.
Да, все объекты (в том числе стековые, типа int и bool) наследуются от объекта object. А этот объект имеет набор виртуальных функций: ToString(), GetHash(), GetType() и Equals(). Другими словами эти функции есть у любого объекта.
Не буду утверждать, но что-то мне подсказывает, что во время приведения типов переполнении памяти быть не может. Когда-то очень давно читал статью на эту тему, но, к сожалению, найти уже не могу. По-моему логика была примерно в том, что на уровне MSIL сначала выделяется память под переменную, а потом происходит приведение. Причем сама операция приведения проходит не в стеке приложения, потому к StackOverflow привести не может.
Хотя тут могу ошибаться.
А говоря о правиле приведения, я имел ввиду именно исключения при выходе за диапазон значений. Т. е. типы с меньшим диапазоном приводятся к большим без явного объявления.
Насчет русских переменных, можно ещё делать вот так: http://pastebin.com/LJA1VHwp
Комментарий для anothersite.ru:
Тоже забавно :) Наверное, предпроцессором можно и ключевые слова заменить?
Комментарий для Евгения Степанищева:
Нет, нельзя. Препроцессора в шарпе как такового нет. http://msdn.microsoft.com/en-us/library/ed8yd1ha%28v=vs.110%29.aspx
Когда си стал strong typed то? :)
Это всё фигня по сравнению с linq :) Там такоооой простор для творчества
Комментарий для Андрей:
С Си я неточно выразился, скорее моё недоумение касалось вот такой вещи:
Комментарий для dinoelq:
Разве это не те же генераторы с itertools из Пайтона? В Пайтоне это компактнее и красивее.
А у меня не получилось объявить переменную int \uD83D\uDE38. Пишет непредвиденный знак \uD83D. Почему так? А вот с собачкой в имени переменной все хорошо. Юзаю Visual C# 2010.
Комментарий для sfersox:
Должно работать, см. пункт 2.4.1 в руководстве ( http://go.microsoft.com/fwlink/?LinkId=199552 ).
Комментарий для Евгения Степанищева:
Хм, получилось. Видимо в примере не корректный юникод используется.
Комментарий для sfersox:
В моём пример? У меня ж компилируется. Правда, это не Visual C# 2010, да и символ из свежего стандарта Юникода.
Комментарий для Евгения Степанищева:
Ну да, именно из примера код не проходит.Может это зависит от системы?
Комментарий для sfersox:
Не удивлюсь. В Винде традиционно всё плохо с Юникодом.
а где традиционно хорошо?
Комментарий для zg.livejournal.com:
На «Маке».