ОБНОВЛЕНИЕ: сегодня я использую этот вопрос в качестве темы моего блога. Спасибо за отличный вопрос. Пожалуйста, смотрите блог для будущих дополнений, обновлений, комментариев и т. Д.
http://blogs.msdn.com/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx
Мне не совсем понятно, что именно вы спрашиваете. «Почему» на вопросы сложно ответить. Но я попробую.
Во-первых, код, который имеет неявное преобразование из char в int (примечание: это не «неявное приведение», это «неявное преобразование») является допустимым, поскольку в спецификации C # четко указано, что существует неявное преобразование из char to int, и в этом отношении компилятор является правильной реализацией спецификации.
Теперь, вы могли бы разумно указать, что вопрос был тщательно задан. Почему происходит неявное преобразование из char в int? Почему разработчики языка считают, что это разумное правило для добавления в язык?
Ну, во-первых, очевидные вещи, которые мешают этому правилу языка, не применяются. Символьный символ реализован в виде 16-разрядного целого числа без знака, которое представляет символ в кодировке UTF-16, поэтому его можно преобразовать в короткую строку без потери точности или, в этом отношении, без изменения представления. Среда выполнения просто переходит от обработки этого шаблона битов как символа к обработке того же шаблона битов, что и для ushort.
Поэтому возможно разрешить преобразование из char в ushort. То, что что-то возможно, не означает, что это хорошая идея. Очевидно, разработчики языка думали, что неявное преобразование char в ushort было хорошей идеей, но неявное преобразование ushort в char - нет. (И поскольку char для ushort - хорошая идея, кажется разумным, что char-to-everything-ushort-go-to также является разумным, следовательно, char to int. Кроме того, я надеюсь, что понятно, почему разрешение явное приведение ushort к char разумно; ваш вопрос касается неявных преобразований.)
Таким образом, у нас фактически есть два связанных вопроса: во-первых, почему плохая идея разрешать неявные преобразования из ushort / short / byte / sbyte в char? и во-вторых,
почему стоит разрешить неявные преобразования из char в ushort?
В отличие от вас, у меня есть оригинальные заметки от команды разработчиков языка. Копаясь в них, мы обнаруживаем некоторые интересные факты.
Первый вопрос описан в примечаниях от 14 апреля 1999 г., где возникает вопрос о том, должно ли быть законным преобразование из байта в символ. В исходной предварительной версии C # это было законно в течение короткого времени. Я слегка отредактировал примечания, чтобы прояснить их без понимания кодовых имен Microsoft до 1999 года. Я также добавил акцент на важные моменты:
[Комитет по проектированию языков] решил предоставить
неявное преобразование из байтов в
символы, так как домен одного
полностью сдерживается другим.
Прямо сейчас, однако, [время выполнения
библиотека] предоставляют только методы записи
которые берут символы и целые, что означает
что байты распечатываются как символы
так как это оказывается лучшим
метод. Мы можем решить это либо
предоставляя больше методов на Writer
класс или путем удаления неявного
преобразование.
Есть аргумент, почему
последнее - правильная вещь.
В конце концов, байтов на самом деле не
символы . Правда, может быть
полезное отображение от байтов до символов, но в конечном итоге 23 не обозначает
то же самое, что персонаж с ascii
значение 23, так же, как 23B
обозначает то же самое, что и 23L. Запрашиваемая
[авторы библиотеки], чтобы обеспечить это
дополнительный метод просто из-за
как работает причуды в нашей системе типов
кажется довольно слабым. Так что я бы
предложить, чтобы мы сделали преобразование
от байта к символу явно.
Затем примечания завершаются решением о том, что byte-char должен быть явным преобразованием, а целочисленное значение-в-диапазоне-char также должно быть явным преобразованием.
Обратите внимание, что в примечаниях к дизайну языка не указывается, почему ushort-to-char также был объявлен недопустимым одновременно, но вы можете видеть, что применяется та же логика. При вызове метода, перегруженного как M (int) и M (char), когда вы передаете ему ushort, есть хорошие шансы, что вы захотите рассматривать ushort как число, а не как символ. И ushort НЕ является символьным представлением так же, как ushort является числовым представлением, поэтому представляется разумным также сделать это преобразование незаконным.
Решение сделать так, чтобы чарс отправился в срочно, было принято 17 сентября 1999 г .; в заметках этого дня по этой теме просто говорится, что "символ в ushort также является законным неявным преобразованием", и все. Дальнейшее изложение того, что происходило в тот день у создателей языка, не видно в заметках.
Тем не менее, мы можем образовать догадки о том, почему неявный char-to-ushort считался хорошей идеей. Ключевой идеей здесь является то, что преобразование из числа в символ является «возможно хитрым» преобразованием. Он берет то, что вы НЕ ЗНАЕТЕ, предназначено для того, чтобы стать персонажем, и решает относиться к нему как к одному. Это похоже на то, что вы хотите отрицать, что вы делаете явно, а не случайно позволяете это. Но обратное гораздо менее хитроумно. В программировании на С существует давняя традиция рассматривать символы как целые числа - получать их базовые значения или делать на них математику.
Короче говоря: кажется разумным, что использование числа в качестве символа может быть случайностью и ошибкой, но также разумно, что использование символа в качестве числа является преднамеренным и желательным. Поэтому эта асимметрия отражена в правилах языка.
Это отвечает на ваш вопрос?