67

为什么将charC# 结果中的两个添加到int类型中?

例如,当我这样做时:

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

pr变量成为一种类型int。我希望它是string一个值为 的类型"RGBYP"

为什么 C# 是这样设计的?添加两个 s 的默认实现不char应该导致string连接chars 的 a,不是int吗?

4

15 回答 15

80

根据char的文档,它可以隐式转换为整数值。该char类型没有定义自定义operator +,因此使用了整数类型。

Eric Lippert 在他的博客文章“为什么 char 隐式转换为 ushort 但反之不行?”的第一条评论很好地解释了没有隐式转换为字符串的理由。:

它在 v1.0 中被考虑过。1999 年 6 月 6 日的语言设计说明说:“我们讨论了是否应该存在这种转换,并决定提供第三种方法来进行这种转换是很奇怪的。[语言] 已经支持 c.ToString() 和 new字符串(c)”。

感谢 JimmiTh找到了那个报价

于 2013-05-31T07:23:17.177 回答
17

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

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

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

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

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

于 2013-05-31T15:08:53.440 回答
8

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

于 2013-05-31T07:19:57.353 回答
7

从 MSDN

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

char 是一个整数类型。这不是一个字符,它是一个数字!

'a'只是数字的简写。

所以添加两个字符会产生一个数字。

看看这个关于添加字节的问题,虽然违反直觉,但它是同一件事。

于 2013-05-31T07:26:10.220 回答
6

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

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

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

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

这在某个时候是 C / C++ 中的一个设计决定(它可以追溯到 70 年代的 C)。

于 2013-05-31T10:27:27.517 回答
6

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

对于二元+... 运算符,操作数被转换为 type T,其中T是 , 的第一个,int并且可以完全表示两个操作数的所有可能值。uintlongulong

所以对于 a char,两者都被转换为int然后添加为ints。

于 2013-05-31T07:30:24.377 回答
5

来自MSDN

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

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

于 2013-05-31T07:26:36.493 回答
4

如前所述,这是因为 char 具有包含其 unicode 值的 Int32 值。

如果要将字符连接成字符串,可以执行以下操作之一:

将一个字符数组传递给一个新字符串:

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';
于 2013-05-31T07:31:49.473 回答
4

A charorSystem.Char是一个整数类型:

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

这意味着它的行为与uint16or完全一样System.UInt16,并且使用运算符添加字符+因此会添加整数值,因为+运算符没有在 中重载char

要将单个字符连接成字符串,请使用StringBuilder.Append(char)new String(char[])

于 2013-05-31T07:36:33.460 回答
3

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

于 2013-05-31T07:24:21.027 回答
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());
于 2013-05-31T21:57:56.767 回答
1

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

于 2013-05-31T07:26:03.697 回答
0

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

于 2013-05-31T14:00:41.783 回答
0

为什么 C# 是这样设计的?添加两个字符的默认实现不应该导致连接字符的字符串,而不是int?

就你想要完成的事情而言,你的意图是不正确的。字符串不是字符的添加,字符串是所谓的“单例”字符串的添加。

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

于 2013-05-31T07:34:10.097 回答
0

您假设 achar是字符串类型。a 的值char可以用单引号之间的字符值表示,但如果有帮助,您应该将其视为提供可读性的抽象,而不是强迫您作为开发人员记住底层值。事实上,它是一种数值类型,因此您不应期望任何字符串操作函数都适用。

至于为什么为什么char + char = int?我不知道。当然,提供隐式转换 toInt32会减轻算术溢出,但是为什么short + short不隐式键入 toint呢?

于 2013-05-31T23:20:22.570 回答