char的+ = b运算符是否与a = a + b相同?

时间:2017-04-06 11:37:11

标签: c#

发现一个有趣的问题,即代码运行后会产生不同的结果:

char c = 'a';

c += 'a';   //passed
c = c + 'a'; //Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)

a += ba=a+b之间有什么区别,或者只是编译器的代码检查错过了吗?

我的观点是char += char在考虑char = (char+char) char = int时可以通过代码检查的原因?

4 个答案:

答案 0 :(得分:44)

C# Specification,第7.17.2节复合赋值:

  

通过应用二元运算符重载决策(第7.3.4节)处理形式x op= y的操作,就好像操作是写x op y一样。然后,

     

...

     

•否则,如果所选运算符是预定义运算符,则所选运算符的返回类型可明确转换为x类型,并且y可隐式转换为类型x或运算符是移位运算符,然后将操作评估为x = (T)(x op y),其中Tx的类型,但评估x除外只有一次

这正是我们在这里的情况。该操作的返回类型为int,但xy的类型均为char,因此会自动为我们插入额外的演员。

(我相信这个规则的存在是因为你无法自己插入一个明确的演员,并且它有点“预期”可行,特别是在xy是相同类型)

答案 1 :(得分:9)

在第二种情况下,失败的是赋值,而不是计算本身。如果你明确地将第二行中的结果转换为char它可以正常工作,实际上以下三行生成相同的IL:

    c += (char)1;
    c = (char)(c + (char)1);
    c = (char)(c + 1);

是的。有区别。

请注意,在第三行中,我没有费心将1转换为char,因为计算只会将其转换回int。

答案 2 :(得分:4)

在这种情况下,结果类型+ =是char,结果类型c +(char)1是int。

以下代码打印:

  

o1 System.Char o2 System.Int32

    public static void Main(string[] args)
    {
        char c = 'a';

        object o1 = c += (char)1;
        object o2 = c + (char)1;

        WriteLine("o1 " + o1.GetType());
        WriteLine("o2 " + o2.GetType());
     }

答案 3 :(得分:2)

用更简单的术语表达Damien的答案:
复合运算符(例如+=-=等)自动将结果转换为目标类型(如果可能)。 因此c += 'a'有效,因为它被评估为c = (char)(c + 'a')

在这种情况下,转换是必要的,因为字符之间的算术运算的返回类型是int(这就是c = c + 'a'无法编译的原因,因为它缺少上面的转换)。