char + char = int?为什么?

时间:2013-05-31 07:18:23

标签: c# .net

为什么在C#结果中添加两个charint类型?

例如,当我这样做时:

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

pr变量变为int类型。我希望它是string类型,其值为"RGBYP"

为什么C#设计得像这样?添加两个char的默认实现不应该是string连接char而不是int吗?

15 个答案:

答案 0 :(得分:78)

根据the documentation of char,它可以隐式转换为整数值。 char类型未定义自定义operator +,因此使用整数。{/ p>

Eric Lippert在blog entry on "Why does char convert implicitly to ushort but not vice versa?"的第一条评论中解释了没有隐式转换为字符串的基本原理:

  

在v1.0中考虑过。语言设计从6月6日开始   1999年说“我们讨论了这种转换是否应该存在,并且   我认为提供第三种方法是很奇怪的   转换。 [该语言]已经支持c.ToString()和new   串(C)”。

(归功于JimmiThfinding that quote

答案 1 :(得分:13)

char是一个值类型,意味着它有一个数值(其UTF-16 Unicode序数)。但是,它不被视为数字类型(如int,float等),因此,+运算符未定义为char。

但是,char类型可以隐式转换为数字int类型。因为它是隐式的,所以允许编译器根据C#规范中规定的一组优先规则为您进行转换。 int是通常尝试过的第一件事。这使+运算符有效,因此执行的操作。

要做你想做的事,先从一个空字符串开始:

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

与char类型不同,字符串类型为Object定义了一个重载的+运算符,它将第二个术语(无论它是什么)转换为使用ToString()的字符串,然后再连接到第一个术语。这意味着不执行隐式转换;现在,您的pr变量被推断为字符串,并且是所有字符值的串联。

答案 2 :(得分:8)

因为单个字符可以转换为Unicode值,并且可以很容易地存储为整数,占用的空间比单个字符串少。

答案 3 :(得分:7)

From the MSDN

  

Char对象的值是16位数字(序数)值。

char是一个整数类型。它不是一个角色,而是一个数字!

'a'只是一个数字的简写。

因此,在数字中添加两个字符结果。

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

答案 4 :(得分:6)

规范的另一个相关位,在4.1.5(积分类型)中将char定义为整数类型:

  

对于二进制+ ...运算符,操作数将转换为T类型,其中Tint中的第一个,uintlongulong可以完全代表两个操作数的所有可能值。

因此对于char,两者都转换为int,然后添加为int

答案 5 :(得分:6)

关键是,许多C#概念来自C ++和C.

在这些语言中,单个字符常量(如“A”)表示为它们的Ascii值,尽管人们可能期望,但它的类型不是char而是int(是'A'是int,与写入相同65)。

因此,添加所有这些值就像写一系列ascii字符代码,即

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

这在某种程度上是C / C ++的设计决定(它可以追溯到70年代的C)。

答案 6 :(得分:5)

来自MSDN

  

在许多情况下可能会发生隐式转换,包括方法   调用和赋值语句。

char可以隐式转换为ushort,int,uint,long,ulong,float,double或decimal。因此,赋值操作隐式地将char转换为int。

答案 7 :(得分:4)

如前所述,这是因为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';

答案 8 :(得分:4)

charSystem.Char是整数类型:

  

表示无符号16位整数的整数类型,其值介于0和65535之间。该类型的可能值集对应于Unicode字符集。

这意味着它的行为与uint16System.UInt16完全相同,因此在+运算符中添加字符会添加整数值,因为+运算符不是已在char中重载。

要使用StringBuilder.Append(char)new String(char[])将单个字符串联成字符串。

答案 9 :(得分:3)

不应该因为那样效率低下。如果想要连接这样的字符,他们应该使用字符串构建器。否则,每次添加都会创建一个临时内存来保存连接的部分字符串,这意味着在您的示例中将需要进行4次临时内存分配。

答案 10 :(得分:2)

Char是16位整数值的文本表示。您只需将int添加到一起。如果要连接字符,则必须将它们转换为字符串。

答案 11 :(得分:1)

1)定义(MSDN):

char关键字用于声明一个16位字符,用于表示全世界大多数已知的书面语言。


2)为什么char与数字类型相似?

A char can be implicitly converted to a numeric type.

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());

答案 12 :(得分:0)

  

为什么C#设计得像这样?不是默认的实现   添加两个字符应该是一个串联的字符串   chars,不是int?

关于你想要完成的事情,你的意图是不正确的。 String不是chars的补充,String是“singleton”字符串的补充。

所以“a”+“b”=>“ab”,如果你考虑到字符串的+运算符超载,这是绝对正确的。 因此'a'代表ASCII字符65,完全一致地说'a'+'b'是131.

答案 13 :(得分:0)

因为char加上另一个char可能超过char变量允许的最大值,所以这就是为什么该操作的结果被转换为int变量。

答案 14 :(得分:0)

您假设char是字符串类型。 char的值可以由单引号之间的字符值表示,但如果它有帮助,您应该认为这是一个提供可读性的抽象,而不是强迫您作为开发人员记住潜在价值。实际上,它是一个数值类型,因此您不应期望任何字符串操作函数适用。

为何选择char + char = int?我不知道。当然,提供隐式转换到Int32可以减轻算术溢出,但是为什么short + short没有隐式输入int