Char + char= int? Зачем?
Почему добавляется два char
в результатах С# к типу int
?
Например, когда я это делаю:
var pr = 'R' + 'G' + 'B' + 'Y' + 'P';
переменная pr
становится типом int
. Я ожидаю, что это будет тип string
со значением "RGBYP"
.
Почему С# создан так? Не была ли реализация по умолчанию добавления двух char
должна приводить к string
, которая объединяет char
s, а не int
?
Ответы
Ответ 1
Подписывая документацию char, он может быть неявно преобразован в целые значения. Тип char
не определяет пользовательский operator +
, поэтому используется для целых чисел.
Обоснование отсутствия неявного преобразования в строку объясняется в первом комментарии Эрика Липперта в блоге в блоге "Почему char конвертировать неявно в ushort, но не наоборот?" :
Это было рассмотрено в версии 1.0. Замечания по оформлению языка с 6 июня 1999 год: "Мы обсуждали, должно ли такое преобразование существовать, и решил, что было бы странно предоставить третий способ сделать это преобразование. [Язык] уже поддерживает как c.ToString(), так и новый String (с)".
(кредит JimmiTh для нахождения этой цитаты)
Ответ 2
char
- это тип значения, означающий, что он имеет числовое значение (его порядковый номер Unicode UTF-16). Тем не менее, он не считается числовым типом (например, int, float и т.д.), И поэтому оператор < > не задан для char.
Однако тип char
может быть неявно преобразован в числовой тип int
. Поскольку он неявный, компилятору разрешено выполнить преобразование для вас, в соответствии с набором правил приоритета, изложенным в спецификации С#. int
- одна из первых вещей, которые обычно пробовали. Это делает оператор +
действительным, и чтобы выполнялась операция.
Чтобы сделать то, что вы хотите, начните с пустой строки:
var pr = "" + 'R' + 'G' + 'B' + 'Y' + 'P';
В отличие от типа char, тип строки определяет перегруженный + оператор для Object, который преобразует второй член, независимо от того, что он есть, в строку, используя ToString()
, прежде чем конкатенировать ее до первого члена. Это означает, что не выполняется неявное литье; ваша переменная pr
теперь выводится как строка и является конкатенацией всех значений символов.
Ответ 3
Поскольку один char может быть преобразован в значение Unicode и может быть легко сохранен как целое число, занимающее меньше места, чем одна символьная строка.
Ответ 4
Из MSDN:
Значение объекта Char - это 16-разрядное числовое (порядковое) значение.
A Char является интегральным типом. Это не символ, это число!
'a'
является просто сокращением числа.
Таким образом, добавление двух символов приводит к числу.
Посмотрите на этот вопрос о добавлении байтов, он, хотя и несовместим, то же самое.
Ответ 5
Еще один соответствующий бит спецификации, в разделе 4.1.5 (Интегральные типы), определяющий char
как интегральный тип:
Для двоичных операторов +
... операнды преобразуются в тип T
, где T
является первым из int
, uint
, long
и ulong
, который может полностью представляют все возможные значения обоих операндов.
Итак, для a char
оба преобразуются в int
, а затем добавляются как int
s.
Ответ 6
Дело в том, что многие концепции С# исходят из С++ и C.
В этих языках одна символьная константа (например, "A" ) представляется как ее значение Ascii, и, несмотря на то, что можно ожидать, она не является char, а int (да "A" - это int, то же самое как запись 65).
Таким образом, добавление всех этих значений подобно написанию серии символов символов ascii, то есть
var pr= 82 + 71 + 66 + ...;
В какой-то момент это было дизайнерское решение в C/С++ (его возвращение к 70 с C).
Ответ 7
От MSDN:
Неявные преобразования могут возникать во многих ситуациях, включая метод вызывать и присваивания.
A char может быть неявно преобразован в ushort, int, uint, long, ulong, float, double или decimal. Таким образом, операция присваивания неявно преобразует char в int.
Ответ 8
Как было сказано, это связано с тем, что char имеет значение Int32, содержащее его значение unicode.
Если вы хотите объединить символы в строку, вы можете выполнить одно из следующих действий:
Передайте массив символов в новую строку:
var pr = new string(new char[] { 'R', 'G', 'B', 'Y', 'P' });
Использовать StringBuilder:
StringBuilder sb = new StringBuilder();
sb.Append('R');
etc...
Начните со строки:
var pr = string.Empty + 'R' + 'G' + 'B' + 'Y' + 'P';
Отправляйте каждого в строку (или просто один будет работать так же хорошо):
var pr = (string)'R' + (string)'G' + (string)'B' + (string)'Y' + (string)'P';
Ответ 9
A char
или System.Char
является интегральным типом:
Интегральный тип, представляющий беззнаковые 16-битные целые числа со значениями между 0 и 65535. Набор возможных значений для этого типа соответствует набору символов Unicode.
Это означает, что он ведет себя точно так же, как a uint16
или System.UInt16
, поэтому добавление символов с помощью оператора +
добавляет интегральные значения, поскольку оператор +
не перегружен в char
.
Чтобы объединить отдельные символы в строку, используйте StringBuilder.Append(char)
или new String(char[])
.
Ответ 10
Это не должно быть, потому что это будет неэффективно. Если бы кто-то хотел конкатенировать такие символы, они должны использовать построитель строк. В противном случае каждое добавление создало бы временную память для хранения объединенной частичной строки, что означало бы, что в вашем примере должно было возникнуть 4 временных выделения памяти.
Ответ 11
A Char - текстовое представление 16-разрядного целочисленного значения. Вы просто добавляете ints вместе. Если вы хотите конкатенировать символы, вам нужно будет отнести их к строкам.
Ответ 12
1) Определение (MSDN):
Ключевое слово char используется для объявления 16-разрядного символа, используемого для представления большинства известных письменных языков в мире.
2) Почему char любит числовые типы?
A char can be implicitly converted to a numeric type.
A char ближе к целому числу, чем к строке. Строка представляет собой только набор объектов char, тогда как целое число может представлять char и наоборот.
3) Примеры
Вы можете просто преобразовать первый из ваших символов в строку, чтобы перехитрить ваш компилятор:
var pr = 'R'.ToString() + 'G' + 'B' + 'Y' + 'P';
Вы также можете определить массив char, а затем использовать конструктор строк:
char[] letters = { 'R', 'G', 'B','Y', 'P' };
string alphabet = new string(letters);
Если вы хотите распечатать символ исключительно, вам всегда нужно преобразовать его в строку, чтобы получить его текстовое представление:
var foo1 = 'F';
MessageBox.Show(foo1.ToString());
Ответ 13
Почему С# создан так? Не было внедрение по умолчанию добавление двух символов должно приводить к строке, которая объединяет символы, а не int?
То, что вы намереваетесь, неверно в отношении того, что вы хотите выполнить.
Строка не является добавлением символов, строка - это дополнение так сказать строк "singleton".
Итак, "a" + "b" = > "ab", что абсолютно правильно, если учесть, что оператор + для строк перегружен.
И, следовательно, "a" представляет ASCII char 65, вполне согласуется с тем, что "a" + "b" равно 131.
Ответ 14
Поскольку char плюс еще один char может превышать максимальное значение, разрешенное для переменной char, то почему результат этой операции преобразуется в переменную int.
Ответ 15
Вы предполагаете, что a char
является строковым типом. Значение a char
может быть представлено символьным значением между одинарными кавычками, но если это помогает, вы должны считать это абстракцией для обеспечения читаемости, а не заставлять вас как разработчика запоминать базовое значение. Это, по сути, тип числового значения, поэтому вам не следует ожидать, что будут применены любые функции манипуляции строкой.
Почему почему char + char = int
? Понятия не имею. Конечно, предоставление неявного преобразования в Int32
уменьшит арифметические переполнения, но тогда почему short + short
неявно набирается на int
?