代码之家  ›  专栏  ›  技术社区  ›  Matthew Scharley

为什么c不为char定义一个加法操作?

c#
  •  7
  • Matthew Scharley  · 技术社区  · 15 年前

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

    为什么下面的代码不起作用?这似乎合乎逻辑。

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

    现在,从上面的链接问题我们可以推断出这里发生了什么:编译器使用隐式char->int转换,然后添加这些值。这使我相信不应该为 char S!这是真的吗?如果是,为什么没有呢?

    编辑: 一般的共识是,没有一个定义的意义比我期望定义的意义更大。

    6 回复  |  直到 9 年前
        1
  •  15
  •   Eric Lippert    15 年前

    首先,说说你的演绎过程。您的推论——这个char被转换为int,因此char上没有定义加法运算符——是spot on,对您来说非常好。但我注意到扣除过程是不必要的。您可以简单地阅读本规范的第7.7.4节,其中清楚地描述了所有内置的加法运算符。简而言之,它们是int+int、uint+uint、long+long、ulong+ulong、float+float、double+double、decimal+decimal、枚举和基础类型、委托组合、字符串+字符串、字符串+对象和对象+字符串。(当然,提升到涉及值类型的那些可以为空的版本。)所以是的,没有接受字符的加法运算符。

    第二,回答你的“为什么不?”--chars有点奇怪。它们的存储是短整数,但它们的语义是字符串中字符的语义。那么应该把一个字符看作它的整数形式还是一个短字符串呢?在本例中,语言设计者决定遵循早期语言(如C)的前导,在对不涉及字符串的字符进行数学运算时,将字符视为整数。如果你想把它们当作短字符串,有很多方法可以把字符转换成字符串。如另一个答案所示,附加空字符串会明确地告诉编译器“这个操作是在字符串上,而不是在字符的整数值上”。

        2
  •  7
  •   John Gietzen    15 年前

    你真正想要的是:

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

    这就是编译器在字符串上使用“+”运算符所做的操作。

    这个速度大约是任何一个的两倍 String.Format 操作。

        3
  •  3
  •   Bob Kaufman    15 年前

    我想一个人应该把注意力集中在这个词上 “为什么” 在你的问题上。在C中,添加两个字符的行为被定义为“添加Unicode值”而不是“连接”。我们一致认为,这可以更合理地定义为“连接”,因为字符串和字符与整数的区别要比过去的生命(例如,C编程语言)大得多。

    “a”是字符常量。传统上,字符常量(至少在C中)只是表示整数的另一种方法。在这种情况下,所述整数的unicode值(‘a’=97,‘b’=98等)。因此,表达式“a”+“b”的意思是将这两个Unicode值相加。

    为了达到你的期望,做

    String foo = "a" + "b";  // double quotes = single-character strings to concatenate
    
        4
  •  3
  •   Jez    15 年前

    如前所述,char被认为是整数而不是字符串的形式,因此从根本上讲,加法操作是添加两个数字,而不是执行串联。您可以将两个字符放入这样的字符串中:

    string str = String.Format("{0}{1}", 'a', 'b');
    
        5
  •  1
  •   Paul Sasik    9 年前

    要使您的字符“添加”,您可以执行以下与原始意图类似的操作之一:

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

    对于foo2示例,您通过插入一个空字符串给编译器一个提示,并分别强制对每个字符进行隐式的字符到字符串转换。

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

        6
  •  0
  •   Konstantin Spirin    15 年前

    您可以对字符串使用addition运算符重载,然后尝试执行以下操作:

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

    但请不要混淆

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

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

    我们的想法是让 运算符+ 对于要启动的字符串,您应该将第一个参数作为字符串来实现这一点。

    这看起来有点像作弊,但这是C-愚蠢和残忍!(实际上是.NET,它没有operator+overload for(char,char)和c试图将char强制转换为int32)。