为什么C#没有为char定义一个加法运算?

时间:2009-10-04 14:40:58

标签: c#

正如标题所说。 Related to this question.

为什么以下代码不起作用?这在逻辑上似乎是合理的。

string foo = 'a' + 'b'; // Fails with an invalid int -> string conversion

现在,从上面的链接问题我们可以推断出这里发生了什么:编译器正在使用隐式char - > int转换,然后添加这些值。这让我相信一定不能为char定义一个加法运算!这是真的,如果是的话,为什么没有呢?

编辑:普遍的共识是,没有一个定义的那么多,我预期定义的那个不是。

6 个答案:

答案 0 :(得分:16)

首先,关于你的演绎过程。你的推论 - 这个char被转换为int,因此没有在char上定义的加法运算符 - 是现货,对你很好。但我注意到扣除过程是不必要的。您可以简单地阅读规范的第7.7.4节,其中清楚地描述了所有内置的附加运算符。简而言之,它们是int + int,uint + uint,long + long,ulong + ulong,float + float,double + double,decimal + decimal,enum-and-underlying类型,委托组合,字符串+字符串,字符串+对象和对象+字符串。 (当然,那些涉及价值类型的那些被提升到可以为空的版本。)所以是的,没有添加运算符可以使用字符。

第二,回答你的“为什么不呢?” - 字符有点奇怪。它们的存储是短整数,但它们的语义是字符串中的字符。那么char应该被视为整数形式还是短字符串?在这种情况下,语言设计者决定遵循早期语言(如C语言)的引导,并在对不涉及字符串的数学进行数学处理时将字符视为整数。如果您想将它们视为短字符串,可以使用多种方法将字符串转换为字符串。如另一个答案所示,附加空字符串,毫不含糊地告诉编译器“此操作是在字符串上,而不是在字符的整数值上”。

答案 1 :(得分:7)

你真正想要的是:

string foo = String.Concat('a', 'b');

编译器对字符串的'+'运算符执行的操作正是如此。

这大约是任何String.Format操作的两倍。

答案 2 :(得分:3)

我在想你的问题应该集中在“why”这个词上。在C#中,添加两个字符的行为已经定义为“添加Unicode值”而不是“连接”。我们一致认为,这可以更合理地定义为“连接”,因为字符串和字符与整数相比,它们与前一生中的实体(例如,C语言编程语言)更加截然不同。

'a'是一个字符常量。传统上,字符常量(至少在C中)只是表示整数的另一种方式。在这种情况下,所述整数的Unicode值('a'= 97,'b'= 98等)。因此,表达式'a'+'b'被认为是指将这两个Unicode值加在一起。

要实现您的期望,请执行

String foo = "a" + "b";  // double quotes = single-character strings to concatenate

答案 3 :(得分:3)

正如已经说过的那样,char被认为是一个整数而不是字符串的形式,所以从根本上说,一个加法操作是添加两个数字,而不是执行连接。你可以在这样的字符串中输入两个字符:

string str = String.Format("{0}{1}", 'a', 'b');

答案 4 :(得分:1)

为了让你的角色“添加”,你可以做一些类似于你原始意图的事情之一:

string foo2 = 'a' + "" + 'b'; //  Succeeds
string foo3 = 'a'.ToString() + 'b'.ToString(); // Succeeds
string foo4 = string.Concat('a', 'b'); // Succeeds

对于foo2示例,您可以通过删除空字符串为编译器提供线索,并为每个char单独强制使用隐式char转换为字符串。

对于foo3示例,您对每个字符使用ToString调用以允许添加两个字符串。

答案 5 :(得分:0)

您可以对字符串使用加法运算符的重载并尝试:

var result = "" + 'a' + 'b';

但请不要与

混淆
var result = 'a' + 'b' + "";  // BAD !!!!!

因为它会将 int 转换为字符串并等于“195”。

我们的想法是让运算符+ 重载以使字符串启动,并且您应该将第一个参数作为字符串来实现此目的。

看起来有点像作弊,但那是C# - 毫无意义和无情! (实际上它是.Net,没有运算符+重载(Char,Char)和C#尝试将Char转换为Int32)。