Ответ 1
Литье приведет к потере данных. Здесь char - 16 бит и int 32 бит. Таким образом, передача будет происходить без потери данных.
Пример реальной жизни: мы можем поместить небольшое судно в большой сосуд, но не наоборот, без внешней помощи.
У меня есть вопрос о неявном преобразовании типа
Почему это неявное преобразование типов работает на С#? Я узнал, что неявный код обычно не работает.
У меня есть пример кода здесь о неявном преобразовании типа
char c = 'a';
int x = c;
int n = 5;
int answer = n * c;
Console.WriteLine(answer);
Литье приведет к потере данных. Здесь char - 16 бит и int 32 бит. Таким образом, передача будет происходить без потери данных.
Пример реальной жизни: мы можем поместить небольшое судно в большой сосуд, но не наоборот, без внешней помощи.
ОБНОВЛЕНИЕ: Я использую этот вопрос в качестве темы моего блога сегодня. Спасибо за большой вопрос. Пожалуйста, см. Блог для будущих дополнений, обновлений, комментариев и т.д.
Мне не совсем понятно, что именно вы спрашиваете. "Почему" вопросы трудно ответить. Но я сделаю снимок.
Сначала код, который имеет неявное преобразование из char в int (обратите внимание: это не "неявный перевод", это "неявное преобразование" ) является законным, поскольку спецификация С# четко заявляет, что существует неявное преобразование из char в int, и в этом отношении компилятор корректно реализует спецификацию.
Теперь вы можете разумно указать, что вопрос был тщательно просит. Почему существует неявное преобразование из char в int? Почему дизайнеры языка считают, что это разумное правило добавить к языку?
Ну, во-первых, очевидные вещи, которые помешали бы этому быть правилом языка, не применяются. A char реализуется как неподписанное 16-битное целое число, которое представляет символ в кодировке UTF-16, поэтому его можно преобразовать в ushort без потери точности или, если на то пошло, без изменения представления. Время выполнения просто переходит от обработки этого битового шаблона как char к обработке одного и того же битового шаблона в виде пользовательского ввода.
Таким образом, можно разрешить преобразование из char в ushort. Теперь, только потому, что что-то возможно, это не значит, что это хорошая идея. Понятно, что разработчики языка думали, что неявное преобразование char в ushort было хорошей идеей, но неявно преобразование ushort в char не является. (И поскольку char для ushort - хорошая идея, кажется разумным, что char -to-anything-that-ushort-go-to также разумно, следовательно, char для int. Кроме того, я надеюсь, что это понятно, почему разумное литье ushort в char разумно, ваш вопрос касается неявных преобразований.)
Итак, у нас на самом деле есть два связанных вопроса: во-первых, почему это плохая идея разрешить неявные преобразования из ushort/short/byte/sbyte в char? и, во-вторых, почему это хорошая идея разрешить неявные преобразования из char в ushort?
В отличие от вас, у меня есть оригинальные заметки из команды по дизайну языков, которые мне доступны. Вырывая их, мы обнаруживаем некоторые интересные факты.
Первый вопрос рассмотрен в примечаниях от 14 апреля 1999 года, где возникает вопрос о том, должно ли оно быть законным для преобразования из байта в char. В исходной предварительной версии С# это было законным в течение короткого времени. Я слегка отредактировал заметки, чтобы сделать их понятными без понимания предварительных выпусков Microsoft-кодов 1999 года. Я также добавил акцент на важные моменты:
[Комитет по разработке языков] решил предоставить неявное преобразование из байтов в символов, так как домен одного из них полностью содержащихся в другом. Однако сейчас [время выполнения библиотека] предоставляют только методы Write которые принимают символы и ints, что означает что байты печатаются как символы так как это становится лучшим метод. Мы можем решить это предоставление большего количества методов в Writer класса или путем удаления неявного преобразование.
Существует аргумент в пользу того, почему последнее - правильная вещь. В конце концов, байты действительно не символы. Правда, может быть полезное отображение от байтов до символов, но в конечном счете 23 не обозначает то же самое, что и персонаж с ascii значение 23, таким же образом, что 23B означает то же, что и 23L. Запрашиваемая [авторов библиотеки], чтобы предоставить дополнительный метод просто из-за как причуда в нашей системе типов работает кажется довольно слабым. Поэтому я бы предположим, что мы делаем преобразование от байта до char явного.
В заключение следует, что байт-to- char должен быть явным преобразованием, а integer-literal-in-range-of-char также должен быть явным преобразованием.
Обратите внимание, что примечания о дизайне языка не вызывают, почему ushort-to- char также были незаконными одновременно, но вы можете видеть, что применяется та же логика. Когда вы вызываете метод, перегруженный как M (int) и M (char), когда вы передаете его в ushort, вероятность хорошая, что вы хотите рассматривать ushort как число, а не как символ. И ushort НЕ является символьным представлением таким же образом, что ushort является числовым представлением, поэтому представляется разумным сделать это преобразование незаконным, а также.
Решение о том, чтобы сделать char перейти к ushort было сделано 17 сентября 1999 года; в примечаниях к дизайну с этого дня на эту тему просто указывается, что "char для ushort также является юридическим неявным преобразованием", и что он. Никакое дальнейшее изложение того, что происходило в главах разработчиков языков, в тот день не видно в заметках.
Однако мы можем сделать обоснованные догадки о том, почему неявный char -to-ushort считается хорошей идеей. Ключевая идея здесь заключается в том, что преобразование из числа в символ является "возможно хитроумным" преобразованием. Это принятие чего-то, что вы не знаете, предназначено быть персонажем и выбирает рассматривать его как одно. Это похоже на то, что вы хотите назвать, что вы делаете явно, а не случайно позволяете это. Но обратное гораздо менее изворотливое. В C-программировании существует долгая традиция обработки символов как целых чисел - для получения их базовых значений или для их математики.
Короче: представляется разумным, что использование числа в качестве символа может быть случайностью и ошибкой, но также представляется разумным, что использование символа в качестве числа является преднамеренным и желательным. Поэтому эта асимметрия отражается в правилах языка.
Отвечает ли это на ваш вопрос?
Основная идея заключается в том, что преобразования, приводящие к потенциальной потере данных, могут быть неявными, тогда как преобразования, которые могут привести к потере данных, должны быть явными (с использованием, например, оператора трансляции).
Таким образом, неявное преобразование из char
в int
будет работать на С#.
[edit] Как указывали другие, char
- это 16-разрядное число в С#, поэтому это преобразование происходит только с 16-разрядного целого числа до 32-разрядного целого числа, что возможно без потери данных. [/править]
С# поддерживает неявные преобразования, часть "обычно не работает", вероятно, исходит из какого-то другого языка, возможно, С++, где некоторые славные реализации string
обеспечивали неявные преобразования для разных типов указателей, создавая некоторые гигантские ошибки в приложениях.
Когда вы на любом языке предоставляете преобразования типов, вы также должны по умолчанию использовать явные преобразования по умолчанию и предоставлять только неявные преобразования для особых случаев.
Из спецификации С#
6.1.2 Неявные числовые преобразования Неявные числовые преобразования:
• От sbyte до short, int, long, float, double или decimal.
• От байта до короткого, ushort, int, uint, long, ulong, float, double или десятичная дробь.
• От short до int, long, float, двойной или десятичный.
• От ushort до int, uint, long, ulong, float, double или decimal.
• От int до long, float, double или десятичная дробь.
• От uint до long, ulong, float, двойной или десятичный.
• От длинного до плавающего, двойного или десятичная дробь.
• От ulong до float, double или десятичная дробь.
• Из char в ushort, int, uint, long, ulong, float, double или десятичная дробь.
• От float до double.
Преобразования из int, uint, long или улонг плавать и длинные или улунговые удвоить может привести к потере точность, но никогда не приведет к потере. Другой неявный числовые преобразования никогда не теряют Информация. Нет никаких подразумеваемых преобразования в тип char, поэтому значения других интегральных типов не автоматически конвертировать в charтип.
На странице MSDN о char (char (ссылка на С#):
A char может быть неявно преобразован в ushort, int, uint, long, ulong, float, double или decimal. Однако нет никаких неявных преобразований из других типов в тип char.
Это потому, что они применили неявный метод от char ко всем этим типам. Теперь, если вы спросите, почему они их реализовали, я действительно не уверен, конечно, чтобы помочь работать с ASCII-представлением символов или что-то в этом роде.
Ядром записи в блоге @Eric Lippert является его обоснованное предположение о причинах такого решения разработчиков языка С#:
"There is a long tradition in C programming of treating characters as integers
-- to obtain their underlying values, or to do mathematics on them."
Это может вызвать ошибки, такие как:
var s = new StringBuilder('a');
Как вы думаете, инициализация StringBuilder инициализируется символом "a", но фактически устанавливает емкость StringBuilder равной 97.
Это работает, потому что каждый символ обрабатывается внутри как число, поэтому приведение неявно.
char неявно приводится к нему числовое значение Unicode, которое является целым числом.
Преобразование имплицита из char в числовые типы не имеет смысла, на мой взгляд, потому что происходит потеря информации. Вы можете увидеть это в этом примере:
string ab = "ab";
char a = ab[0];
char b = ab[1];
var d = a + b; //195
Мы поместили все фрагменты информации из строки в символы. Если по какой-либо причине сохраняется только информация из d, все, что осталось нам, - это номер, который не имеет смысла в этом контексте и не может использоваться для восстановления ранее предоставленной информации. Таким образом, наиболее полезным способом было бы неявно преобразовать "сумму" символов в строку.