char = a + b的char操作符是否与a = a + b相同?
发现一个有趣的问题,下面的代码运行一个不同的结果:
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 += b
和a=a+b
之间是否有区别,或者只是编译器的代码检查错过了?
我的观点是为什么char += char
可以通过代码检查,而char = (char+char)
认为是char = int
?
C#规范 ,第7.17.2节复合赋值:
x op= y
forms的x op= y
是通过应用二元运算符重载分辨率(§7.3.4)来处理的,就好像操作被写入x op y
。 然后,…
•否则,如果选定的运算符是预定义的运算符,如果所选运算符的返回types可以明确地转换为
x
的types,并且如果y
可以隐式转换为x
的types,或者运算符是移位运算符,则操作被评估为x = (T)(x op y)
,其中T
是x
的types,除了x
只被评估一次
而这正是我们在这里的情况。 操作的返回types是int
但是x
和y
的types都是char
,所以为我们自动插入一个额外的types。
(我相信这个规则是存在的,因为没有地方可以插入一个明确的演员,这是“预期”的工作,特别是在x
和y
是相同types的情况下)
在第二种情况下,这是失败的任务,而不是计算本身。 如果你明确地将结果在第二行中转换为字符,它可以正常工作,而且下面的三行生成的是相同的IL:
c += (char)1; c = (char)(c + (char)1); c = (char)(c + 1);
所以是的。 它们是有区别的。
注意在第三行我没有打扰把1
转换为char
因为计算只是将其转换回int。
在这种情况下+ =的结果types是char,并且生成的c +(char)1的types是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()); }
用简单的话来说明达明的答案:
复合运算符(例如+=
, -=
等)自动将结果转换为目标types(如果可能的话)。 因此, c += 'a'
起作用,因为它被评估为c = (char)(c + 'a')
。
在这种情况下,转换是必要的,因为字符之间的算术运算的返回types是int
(这就是为什么c = c + 'a'
不能编译,因为它缺less上面的转换)。