2013-05-31 4 views
57

Почему добавляется два char в результатах C# до int?char + char = int? Зачем?

Например, когда я делаю это:

var pr = 'R' + 'G' + 'B' + 'Y' + 'P'; 

переменная pr становится int типа. Я ожидаю, что это будет тип string со значением "RGBYP".

Почему C# разработан так? Не была ли реализация по умолчанию добавлением двух char s должна приводить к string, которая объединяет char s, а не int?

+34

Интересно, что вы фактически не добавляете 'char', так как C# не определяет встроенный + оператор для типа. Однако 'char' неявно конвертируется в' int', поэтому компилятор выбирает версию 'int' оператора + при выполнении разрешения перегрузки. И, конечно, результатом этого оператора является еще один «int». (Обратите внимание, что «конечно» немного смешно говорить, так как «короткий» + «короткий» на самом деле является «int», а не «конечно» ответом другого «короткого»!) – dlev

+3

Одна из многих функций унаследованный от C. 'char' является интегральным типом в C, а также в C#. Изменение поведения типа без уважительной причины (вы можете создавать строки из индивидуального 'char' легко используя другие функции) будет раздражать пользователей, привыкших к поведению C/C++. – Gorpik

+2

не является символом в его самом базовом уровне типа int? – user13267

ответ

8

Поскольку один символ может быть преобразован в значение Unicode и может быть легко сохранен как целое число, занимающее меньше места, чем одна символьная строка.

+3

+1 хороший ответ, но добавьте еще описание – Freelancer

+1

Есть ли какие-либо источники для поддержки этого? почему так происходит? – aiapatag

+2

'char' - это кодовая точка юникода, а не символ ASCII. – Dirk

75

Согласование с the documentation of char может быть неявно преобразовано в целочисленные значения. Тип char не определяет настраиваемый operator +, поэтому используется для целых чисел.

Обоснования что нет никакого неявного преобразования в строку объясняются хорошо в первом комментарии от Eric Липпертом В своем blog entry on "Why does char convert implicitly to ushort but not vice versa?":

Он был рассмотрен в версии 1.0. В примечаниях к языковому дизайну от 6 июня 1999 говорится: «Мы обсуждали, должно ли такое преобразование существовать, и решил, что было бы странным предоставить третий способ сделать это. . [Язык] уже поддерживает как c.ToString () и новый Строка (c) ".

(кредит JimmiTh для finding that quote)

+16

Просто добавьте причину, почему он был спроектирован именно так - именно поэтому нет никакого неявного преобразования в строку (согласны ли мы с обоснованием или нет), согласно Эрику Липперту: «Это рассматривалось в 1.0. В примечаниях к языковому дизайну от 6 июня 1999 года говорилось: «Мы обсуждали, должно ли такое преобразование существовать, и решили, что было бы странно предоставить третий способ сделать это преобразование. [Язык] уже поддерживает как c.ToString(), так и новый String (с)». – JimmiTh

+0

@JimmiTh Очень приятно! У вас есть ссылка на эту цитату случайно? – Dirk

+7

http://blogs.msdn.com/b/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx - это в Lippert's ответьте на первый комментарий. – JimmiTh

3

Это не должно, потому что это было бы неэффективно. Если бы кто-то хотел конкатенировать такие символы, они должны использовать построитель строк. В противном случае каждое добавление создало бы временную память для удержания объединенной частичной строки, что означало бы, что в вашем примере должно было возникнуть 4 временных выделения памяти.

+0

Эффективность здесь не имеет значения, это семантика языка, который решает это. Это также неэффективно для того, чтобы объединить строки, такие как «foo» + «bar» ', но это не мешает ему быть возможным, и никто не будет использовать язык, разработчики которого решили не иметь оператора конкатенации строк в имя защиты от вас. – Jon

2

Char - текстовое представление 16-разрядного целочисленного значения. Вы просто добавляете ints вместе. Если вы хотите конкатенировать символы, вам придется отнести их к строкам.

7

From the MSDN:

Значение объекта Char является числовым значением 16-бит (порядковое).

Шар является интегральным типом. Это не символ, это число!

'a' - это только сокращенное число.

Таким образом, добавление двух символов приводит к числу.

Have a look at this question about adding bytes, it is, although counterintuitive, the same thing.

5

От MSDN:

Неявных преобразования могут возникнуть во многих ситуациях, в том числе метод призыва и операторов присваивания.

полукокса может быть неявно преобразован в UShort, INT, UINT, длинные, ULong, поплавок, двойной или десятичной. Таким образом, операция присваивания неявно преобразует char в int.

+2

Назначение - это * не *, что вызывает неявное преобразование. Посредством присваивания времени существует значение 'int', ожидающее от результата оператора' int' +. – dlev

6

Другие важные бита спецификации, в разделе 4.1.5 (интегральные типов), определив char в качестве интегрального типа:

для бинарных + ... операторов, операнды преобразуются к типу T , где T является первым из int, uint, long и ulong, которые могут полностью представлять все возможные значения обоих операндов.

Таким образом, для char, и преобразуются в int, а затем добавляют в качестве int с.

+0

+1. Вы можете добавить ссылку? –

+1

[Не совсем] (http://stackoverflow.com/questions/127776/where-can-you-find-the-c-sharp-language-specifications), я думаю, вам нужно [загрузить все это] (http : //www.microsoft.com/en-gb/download/details.aspx ID = 7029). – Rawling

4

Как уже было сказано, это потому, что символ имеет значение 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'; 
+2

Его значение Unicode, а не ASCII-код. C# не использует ASCII. – Gorpik

+0

@ Gorpik Ну, я имел в виду в этом конкретном случае, так как значения Unicode таблицы ASCII одинаковы, не так ли? – Ashigore

+0

Да, это потому, что Unicode был разработан для обеспечения совместимости с ASCII. Но зачем говорить что-то, что просто случайно, и для небольшого подмножества всех возможных значений «char», когда вы можете сказать правильную вещь так же легко? C# использует Unicode, а не ASCII. – Gorpik

0

Почему C# разработан, как это? Не была ли реализация по умолчанию , добавив два символа в результате строки, которая объединяет символы , а не int?

То, что вы назначили, неверно в отношении того, что вы хотите выполнить. Строка не является добавлением символов, строка - это дополнение так сказать строк «singleton».

Так что «a» + «b» => «ab», что абсолютно правильно, если учесть, что оператор + для строк перегружен. И, следовательно, 'a' представляет символ ASCII 65, он абсолютно согласен сказать, что 'a' + 'b' равен 131.

4

char или System.Char является составным типом:

Составного типа, представляющего беззнаковых 16-битных чисел со значениями от 0 до 65535. Набор возможных значений для данного типа соответствует набору символов Unicode.

Это означает, что он ведет себя так же, как uint16 или System.UInt16, и добавление символов с оператором + поэтому добавляет интегральные значения, так как оператор + не перегружен в char.

Чтобы объединить отдельные символы в строку, используйте StringBuilder.Append(char) или new String(char[]).

6

Дело в том, что многие C# концепции исходят от C++ и C.

В этих языках константа, один символ (например, «A») представляется в виде их Ascii значения, и, несмотря на то, что можно ожидать, это тип не char, а int (да 'A' - это int, то же самое, что и запись 65).

Таким образом, добавление всех этих значений, как писать серию кодов символов ASCII, т.е.

var pr= 82 + 71 + 66 + ...; 

Это было дизайнерское решение в C/C++ в какой-то момент (его вернуться в 70-е годы с C).

0

Поскольку символ char плюс другой может превышать максимальное значение, разрешенное для переменной char, поэтому результат этой операции преобразуется в переменную int.

+0

Неправильно. short + short может превышать значение короткого, так же как любые другие два числовых типа могут суммироваться до значения, большего чем их тип может хранить. Ни в одном из этих случаев не происходит автоматического расширения числа выполненных номеров; значение просто переполняется и младшие значащие биты сохраняются. Вместо этого это происходит потому, что char не определяет оператор +, но тип, к которому он может быть неявно преобразован (int), определяет этот оператор. – KeithS

+0

Хорошо, спасибо за ваше объяснение !! –

11

char - тип значения, то есть он имеет числовое значение (его порядковый номер Юникода UTF-16). Однако он не считается числовым типом (например, int, float и т. Д.), Поэтому оператор + не задан для char.

Тип char может, однако, быть неявным образом преобразован в числовой тип int. Поскольку это неявно, компилятору разрешено выполнить преобразование для вас, в соответствии с набором правил приоритета, изложенным в спецификации C#. int - одна из первых вещей, которые обычно пробовали. Это делает оператор + действительным, и поэтому это операция выполнена.

Чтобы сделать то, что вы хотите, начните с пустой строкой:

var pr = "" + 'R' + 'G' + 'B' + 'Y' + 'P'; 

В отличие от символьного типа, тип строка определяет перегруженный оператор + для объекта, который преобразует второй член, какой бы она есть, в строка, использующая ToString(), прежде чем конкатенировать ее до первого члена. Это означает, что не выполняется неявное литье; ваша переменная pr теперь выводится как строка и является конкатенацией всех значений символов.

1

1) Определение (MSDN):

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


2) Почему символ делает как числовые типы?

A char can be implicitly converted to a numeric type. 

полукокса ближе к целому числу, чем в строку. Строка - это только совокупность объектов char, тогда как целое число может представлять символ и наоборот.


3) Примеры

Вы можете просто конвертировать первый из символов в строку, чтобы перехитрить ваш компилятор:

var pr = 'R'.ToString() + 'G' + 'B' + 'Y' + 'P'; 

Вы также можете определить массив символов, а затем используйте конструктор строк:

char[] letters = { 'R', 'G', 'B','Y', 'P' }; 
string alphabet = new string(letters); 

Если yo и хочет, чтобы напечатать символ только, вы всегда должны преобразовать его в строку, чтобы получить его текстовое представление:

var foo1 = 'F'; 
MessageBox.Show(foo1.ToString()); 
0

Вы полагаете, что char строковый тип. Значение char может быть представлено значением символа между одинарными кавычками, но если это помогает, вы должны считать это абстракцией для обеспечения удобочитаемости, а не заставлять вас как разработчика запоминать базовое значение. Это, фактически, тип числового значения, поэтому вам не следует ожидать, что любые функции манипуляции строкой будут применимы.

Как почему почему char + char = int? Понятия не имею. Конечно, предоставление неявного преобразования в Int32 уменьшило бы арифметические переполнения, но тогда почему short + short неявно вводится в int?

Смежные вопросы