简体   繁体   English

字符 + 字符 = 整数? 为什么?

[英]char + char = int? Why?

Why is adding two char in C# results to an int type?为什么将 C# 结果中的两个char添加到int类型?

For example, when I do this:例如,当我这样做时:

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

the pr variable becomes an int type. pr变量变为int类型。 I expect it to be a string type with a value of "RGBYP" .我希望它是一个值为"RGBYP"string类型。

Why is C# designed like this?为什么 C# 是这样设计的? Wasn't the default implementation of adding two char s should be resulting to a string that concatenates the char s, not int ?添加两个char的默认实现不是应该导致连接charstring ,而不是int吗?

Accoding to the documentation of char it can be implicitly converted into integer values. 根据 char 的文档,它可以隐式转换为整数值。 The char type doesn't define a custom operator + so the one for integers is used. char类型未定义自定义operator +因此使用整数operator +

The rationale for there being no implicit conversion to string is explained well in the first comment from Eric Lippert in his blog entry on "Why does char convert implicitly to ushort but not vice versa?"没有隐式转换为字符串的基本原理在 Eric Lippert 在他的博客文章“为什么 char 隐式转换为 ushort 但反之亦然?”的第一条评论中得到了很好的解释 :

It was considered in v1.0.它在 v1.0 中被考虑过。 The language design notes from June 6th 1999 say "We discussed whether such a conversion should exist, and decided that it would be odd to provide a third way to do this conversion. [The language] already supports both c.ToString() and new String(c)". 1999 年 6 月 6 日的语言设计说明说“我们讨论了是否应该存在这样的转换,并决定提供第三种方法来进行这种转换会很奇怪。[语言] 已经支持 c.ToString() 和 new字符串(c)”。

(credit to JimmiTh for finding that quote ) 感谢 JimmiTh 找到了那个报价

char is a value type, meaning it has a numerical value (its UTF-16 Unicode ordinal). char是一种值类型,意味着它有一个数值(它的 UTF-16 Unicode 序数)。 However, it is not considered a numeric type (like int, float, etc) and therefore, the + operator is not defined for char.但是,它不被视为数字类型(如 int、float 等),因此,没有为 char 定义 + 运算符。

The char type can, however, be implicitly converted to the numeric int type.但是, char类型可以隐式转换为数字int类型。 Because it's implicit, the compiler is allowed to make the conversion for you, according to a set of rules of precedence laid out in the C# spec.因为它是隐式的,所以允许编译器根据 C# 规范中规定的一组优先级规则为您进行转换。 int is one of the first things normally tried. int是通常尝试的第一件事。 That makes the + operator valid, and so that's the operation performed.这使得+运算符有效,这就是执行的操作。

To do what you want, start with an empty string:要执行您想要的操作,请从一个空字符串开始:

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

Unlike the char type, the string type defines an overloaded + operator for Object, which transforms the second term, whatever it is, into a string using ToString() before concatenating it to the first term.与 char 类型不同,string 类型为 Object 定义了一个重载的 + 运算符,它在将第二项(无论它是什么ToString()与第一项连接之前使用ToString()将其转换为字符串。 That means no implicit casting is performed;这意味着不执行隐式转换; your pr variable is now inferred as a string and is the concatenation of all character values.您的pr变量现在被推断为一个字符串,并且是所有字符值的串联。

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

From the MSDN :从 MSDN

The value of a Char object is a 16-bit numeric (ordinal) value. Char 对象的值是一个 16 位数字(序数)值。

A char is an integral type. char 是一个整数类型。 It is NOT a character, it is a number!它不是一个字符,它是一个数字!

'a' is just shorthand for a number. 'a'只是数字的简写。

So adding two character results in a number.所以添加两个字符会产生一个数字。

Have a look at this question about adding bytes, it is, although counterintuitive, the same thing. 看看这个关于添加字节的问题,虽然违反直觉,但这是同一件事。

Another relevant bit of the spec, in section 4.1.5 (Integral Types) having defined char as an integral type:规范的另一个相关部分,在第 4.1.5 节(整数类型)中将char定义为整数类型:

For the binary + ... operators, the operands are converted to type T , where T is the first of int , uint , long and ulong that can fully represent all possible values of both operands.对于二进制+ ... 运算符,操作数被转换为T类型,其中Tintuintlongulong ,可以完全表示两个操作数的所有可能值。

So for a char , both are converted to int and then added as int s.因此,对于char ,两者都转换为int然后添加为int s。

The point is, that many C# concepts are coming from C++ and C.关键是,许多 C# 概念都来自 C++ 和 C。

In these languages a single character constant (like 'A') is represented as their Ascii value, and despite what one may expect, it's type is not char but int (yes 'A' is an int, the same as writing 65).在这些语言中,单个字符常量(如“A”)被表示为它们的 Ascii 值,尽管人们可能会预料到,它的类型不是 char 而是 int(是的,“A”是一个 int,与编写 65 相同)。

Thus, the addition of all these values is like writing a series of ascii character codes, ie因此,将所有这些值相加就像编写一系列 ascii 字符代码,即

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

This has been a design decision in C / C++ at some point (its going back to the 70's with C).这在某个时候是 C/C++ 中的一个设计决定(它可以追溯到 70 年代的 C)。

From MSDN :MSDN

Implicit conversions might occur in many situations, including method invoking and assignment statements.隐式转换可能发生在许多情况下,包括方法调用和赋值语句。

A char can be implicitly converted to ushort, int, uint, long, ulong, float, double, or decimal. char 可以隐式转换为 ushort、int、uint、long、ulong、float、double 或 decimal。 Thus that assignment operation implicitly converts char to int.因此,赋值操作隐式地将 char 转换为 int。

As has been said, it is because a char has the Int32 value containing its unicode value.如前所述,这是因为 char 具有包含其 unicode 值的 Int32 值。

If you want to concatenate chars into a string you can do one of the following:如果要将字符连接成字符串,可以执行以下操作之一:

Pass an array of chars to a new string:将字符数组传递给新字符串:

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

Use a StringBuilder:使用 StringBuilder:

StringBuilder sb = new StringBuilder();
sb.Append('R');
etc...

Start off with a string:从字符串开始:

var pr = string.Empty + 'R' + 'G' + 'B' + 'Y' + 'P';

Cast each to a string (or just the 1st one will work just as well):将每个转换为一个字符串(或者只是第一个也可以):

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

A char or System.Char is an integral type: charSystem.Char是一个整数类型:

An integral type representing unsigned 16-bit integers with values between 0 and 65535. The set of possible values for the type corresponds to the Unicode character set.表示值在 0 到 65535 之间的无符号 16 位整数的整数类型。该类型的可能值集对应于 Unicode 字符集。

This means that it behaves exactly like a uint16 or System.UInt16 , and adding chars with the + operator therefore adds the integral values, because the + operator is not overloaded in char .这意味着它的行为与uint16System.UInt16完全一样,并且使用+运算符添加字符因此会添加整数值,因为+运算符在char没有重载。

To concatenate individual chars into a string use StringBuilder.Append(char) or new String(char[]) .要将单个字符连接成字符串,请使用StringBuilder.Append(char)new String(char[])

It shouldn't because that would be inefficient.不应该,因为那会效率低下。 If one wanted to concatenate the chars like that they should use string builder.如果想连接这样的字符,他们应该使用字符串生成器。 Otherwise each addition would create a temporary memory to hold the concatinated partial string, which would mean that in your example 4 temporary memory allocations would have to occur.否则,每次添加都会创建一个临时内存来保存连接的部分字符串,这意味着在您的示例中,必须进行 4 个临时内存分配。

A Char is a textual representation of a 16-bit integer value. Char 是 16 位整数值的文本表示。 You are simply adding ints together.您只是将整数加在一起。 If you want to concatenate chars, you'll have to cast them to strings.如果要连接字符,则必须将它们转换为字符串。

1) Definition (MSDN): 1)定义(MSDN):

The char keyword is used to declare a 16-bit character, used to represent most of the known written languages throught the world. char 关键字用于声明一个 16 位字符,用于表示世界上大多数已知的书面语言。


2) Why char does like numeric types? 2) 为什么 char 喜欢数字类型?

A char can be implicitly converted to a numeric type.

A char is closer to an integer than to a string. char 更接近整数而不是字符串。 A string is only a collection of char objects, whereas an integer can present a char and vice versa.字符串只是字符对象的集合,而整数可以表示字符,反之亦然。


3) Examples 3) 例子

You can simply convert the first of your chars to a string, to outwit your compiler:您可以简单地将第一个字符转换为字符串,以智胜编译器:

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

You could also define a char array and then use the string constructor:您还可以定义一个字符数组,然后使用字符串构造函数:

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

If you want to print out a character solely, you always have to convert it to a string, to get its text representation:如果你想单独打印一个字符,你总是必须把它转换成一个字符串,以获得它的文本表示:

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

Why is C# designed like this?为什么 C# 是这样设计的? Wasn't the default implementation of adding two chars should be resulting to a string that concatenates the chars, not int?添加两个字符的默认实现是不是应该生成一个连接字符的字符串,而不是 int?

What you intended is not correct in respect to what you want to accomplish.就您想要完成的事情而言,您的意图是不正确的。 A String is not an addition of chars, a String is an addition of so to say "singleton" strings.字符串不是字符的加法,字符串是所谓的“单例”字符串的加法。

So "a"+"b"=>"ab", which is absolutely correct if you take into account, that the + operator for strings is overloaded.所以"a"+"b"=>"ab",如果你考虑到字符串的 + 运算符是重载的,这是绝对正确的。 And hence 'a' represents the ASCII char 65, it is totally consistent to say, that 'a'+'b' is 131.因此'a'代表ASCII字符65,完全一致地说'a'+'b'是131。

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

You are assuming that a char is a string type.您假设char是字符串类型。 The value of a char can be represented by a character value between single quotes, but if it helps, you should consider that to be an abstraction to provide readability, rather than forcing you as the developer to memorize the underlying value. char的值可以用单引号之间的字符值表示,但如果有帮助,您应该将其视为提供可读性的抽象,而不是强迫您作为开发人员记住底层值。 It is, in fact, a numeric value type, so you should not expect any string manipulation functions to be applicable.实际上,它是一种数值类型,因此您不应期望任何字符串操作函数都适用。

As to why why char + char = int ?至于为什么为什么char + char = int I have no idea.我不知道。 Certainly, providing implicit conversion to Int32 would mitigate arithmetic overflows, but then why is short + short not implicitly typed to int ?当然,提供到Int32隐式转换会减轻算术溢出,但是为什么short + short没有隐式输入为int呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM