ОБНОВЛЕНИЕ: Сегодня я использую этот вопрос как тему своего блога. Спасибо за большой вопрос. Пожалуйста, см. Блог для будущих дополнений, обновлений, комментариев и т. Д.
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 до int, и в этом отношении компилятор корректно выполняет спецификацию.
Теперь вы можете с уверенностью сказать, что вопрос был тщательно просит. Почему существует неявное преобразование из char в int? Почему дизайнеры языка считают, что это разумное правило, чтобы добавить к языку?
Ну, во-первых, очевидные вещи, которые предотвращают это из правила языка не применяются. Символ реализован как неподписанное 16-битное целое число, которое представляет символ в кодировке UTF-16, поэтому его можно преобразовать в ushort без потери точности или, если на то пошло, без изменения представления. Время выполнения просто идет от обработки этого битового шаблона как символа для обработки того же битового шаблона, что и пользовательское.
Поэтому возможно, чтобы разрешить преобразование из char в ushort. Теперь, только потому, что что-то возможно, это не значит, что это хорошая идея. Очевидно, разработчики языка думали, что неявное преобразование char в ushort было хорошей идеей, но неявное преобразование ushort в char не является. (И поскольку char для ushort является хорошей идеей, кажется разумным, что char-to-anything-that-ushort-go-to также разумно, следовательно, char для int. Кроме того, я надеюсь, что понятно, почему можно дать разумный вопрос: почему ваш вопрос связан с неявным преобразованием.)
Итак, у нас на самом деле есть два взаимосвязанных вопроса: во-первых, почему это плохая идея разрешить неявные преобразования из ushort/short/byte/sbyte на char? и во-вторых, Почему это хорошая идея, чтобы разрешить неявные преобразования из char в ushort?
В отличие от вас, у меня есть оригинальные заметки от команды дизайна языка в моем распоряжении. Вырывая их, мы обнаруживаем некоторые интересные факты.
Первый вопрос освещен в примечаниях от 14 апреля 1999 года, где возникает вопрос о том, должно ли оно быть законным для преобразования с байта на символ. В оригинальной предварительной версии C# это было законным в течение короткого времени. Я слегка отредактировал заметки, чтобы сделать их понятными без понимания названий кодов Microsoft, выпущенных в 1999 году. Я также добавил акцент на важных моментах:
[Язык дизайна комитет] был выбран, чтобы обеспечить неявное преобразование из байтов в символов, так как область одного является полностью содержавшимся другой. Прямо сейчас, однако, [библиотека времени выполнения ] только обеспечивает методы Write , которые принимают символы и Интс, а это означает, что байты распечатать как символы , так что в конечном итоге является лучшим метода. Мы можем решить это либо , предоставляя больше методов на классе Writer , либо путем удаления неявного преобразования .
Существует аргумент в пользу того, почему последним является правильной вещью. В конце концов, байт действительно не символов. Правда, может быть полезным отображение от байтов до символов, но в конечном счете, 23 не обозначает то же самое, как символ с ASCII значением 23, таким же образом, что 23B обозначает то же самое, 23L. Запрашивая [авторов библиотеки], чтобы предоставить этот дополнительный метод просто из-за , как причуда в нашей системе типов работает выглядит довольно слабым. Поэтому я хотел бы предположить, что мы делаем преобразование от байта к ядру char.
Примечания затем заключают с принятием решения о том, что byte-to-char должно быть явным преобразованием, а целочисленный-literal-in-range-of-char также должен быть явным преобразованием.
Обратите внимание, что в примечаниях к языковому дизайну не вызывается, почему ushort-to-char также был незаконным в одно и то же время, но вы можете видеть, что применяется та же логика.Когда вы вызываете метод, перегруженный как M (int) и M (char), когда вы передаете его в ushort, вероятность хорошая, что вы хотите рассматривать ushort как число, а не как символ. И пользовательское обозначение НЕ является символьным представлением таким же образом, что пользовательское обозначение представляет собой числовое представление, поэтому представляется разумным сделать это обращение незаконным.
Решение о том, чтобы заставить человека отправиться в распоряжение, было сделано 17 сентября 1999 года; в примечаниях к дизайну с этого дня на эту тему просто указывается, что «char to ushort также является законным неявным преобразованием», и все. Никакое дальнейшее изложение того, что происходило в головах дизайнера языка, в этот день очевидно в заметках.
Однако мы можем сделать образованные догадки относительно того, почему неявный char-to-ushort считается хорошей идеей. Ключевая идея здесь заключается в том, что преобразование из числа в символ является «возможно хитроумным» преобразованием. Он берет то, что вы не знаете, предназначено быть персонажем и предпочитает рассматривать его как одно. Это похоже на то, что вы хотите назвать, что вы делаете явно, а не случайно позволяете это. Но обратное гораздо менее изворотливое. В C-программировании существует долгая традиция обработки символов как целых чисел - для получения их базовых значений или для их математики.
Вкратце: представляется разумным, что использование числа в качестве символа может быть случайностью и ошибкой, но также представляется разумным, что использование символа в качестве числа является преднамеренным и желательным. Поэтому эта асимметрия отражается в правилах языка.
Ответит ли это на ваш вопрос?
Это действительно хороший вопрос. В C символ более или менее является синонимом байта, они оба являются числовыми типами. В C#, однако, символ является символом unicode ... –
, поэтому ответ будет заключаться в том, что символ является символом Unicode, поэтому он работает на C#? – tintincutes
Как раз для того, чтобы исправить ваше использование жаргона - это не подразумеваемый литой. Это неявное преобразование. «Кастинг» - это использование оператора трансляции; неявное преобразование - это преобразование, которое НЕ требует оператора трансляции. –