为什么在C#结果中添加两个char
到int
类型?
例如,当我这样做时:
var pr = 'R' + 'G' + 'B' + 'Y' + 'P';
pr
变量变为int
类型。我希望它是string
类型,其值为"RGBYP"
。
为什么C#设计得像这样?添加两个char
的默认实现不应该是string
连接char
而不是int
吗?
答案 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)”。
答案 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)
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
类型,其中T
是int
中的第一个,uint
,long
和ulong
可以完全代表两个操作数的所有可能值。
因此对于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)
char
或System.Char
是整数类型:
表示无符号16位整数的整数类型,其值介于0和65535之间。该类型的可能值集对应于Unicode字符集。
这意味着它的行为与uint16
或System.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
?