Идентификаторы в 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
Поделиться
Отправить
 427   2013   csharp
21 комментарий
Raiden 2013

Console.WriteLine («Первый байт равен: » + байтраз); // строки спокойно складываются с числами

У любого объекта есть виртуальная функция ToString(), которая и вызывается неявно при конкатенации строк.

Raiden 2013

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

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Raiden:

Как в Джаваскрипте? Интересно. Я посмотрел, даже пустой объект что-то возвращает:

var @object = new {};
Console.WriteLine (»» + @object); // вернёт {}

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Raiden:

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

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

Raiden 2013

Как в Джаваскрипте? Интересно. Я посмотрел, даже пустой объект что-то возвращает

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

Raiden 2013

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

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

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

DuMOHsmol (anothersite.ru) 2013

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для anothersite.ru:

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

PastorGL 2013

Комментарий для Евгения Степанищева:

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

Нет, нельзя. Препроцессора в шарпе как такового нет. http://msdn.microsoft.com/en-us/library/ed8yd1ha%28v=vs.110%29.aspx

Андрей 2013

тут будет как в Гоу или Си

Когда си стал strong typed то? :)

dinoelq 2013

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Андрей:

Когда Си стал строго типизированным-то? :)

С Си я неточно выразился, скорее моё недоумение касалось вот такой вещи:

int main() {
char *str = «Hello»;
int digit = 1;
printf(«%s», str + digit);
}

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dinoelq:

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

Разве это не те же генераторы с itertools из Пайтона? В Пайтоне это компактнее и красивее.

sfersox 2013

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для sfersox:

А у меня не получилось объявить переменную int \uD83D\uDE38

Должно работать, см. пункт 2.4.1 в руководстве ( http://go.microsoft.com/fwlink/?LinkId=199552 ).

sfersox 2013

Комментарий для Евгения Степанищева:

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для sfersox:

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

sfersox 2013

Комментарий для Евгения Степанищева:

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для sfersox:

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

zg (zg.livejournal.com) 2013

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

Евгений Степанищев (bolknote.ru) 2013

Комментарий для zg.livejournal.com:

На «Маке».

Популярное