对于这个C#,a==true
:
bool a = "hello" + '/' + "world" == "hello/world";
对于这个C#,b==true
:
bool b = "hello" + + '/' + "world" == "hello47world";
我想知道这是怎么回事,更重要的是,为什么C#语言架构师会选择这种行为?
答案 0 :(得分:51)
第二个+
正在将char
转换为int
,并将其添加到字符串中。 /
的ASCII值为47,然后由另一个+运算符转换为字符串。
斜杠前的+
运算符隐式将其强制转换为int。请参阅MSDN上的+ Operator,然后查看“一元加”。
对数字类型进行一元+运算的结果就是操作数的值。
我实际上通过查看+
运营商实际呼叫的内容来解决这个问题。 (我认为这是ReSharper或VS 2015功能)
答案 1 :(得分:26)
那是因为您使用的是一元运算符+
。它与一元运算符-
类似,但它不会更改操作数的符号,因此它在此处唯一的作用是将字符'/'
隐式转换为int
。
+'/'
的值是/
的字符代码,即47。
代码与:
相同bool b = "hello" + (int)'/' + "world" == "hello47world";
答案 2 :(得分:16)
为什么,我听到你问,char
是否专门针对运营商int operator +(int x)
而不是many other fine unary +
operators available之一?:
char
没有任何一个,编译器会查看预定义一元+
运营商。char
,因此编译器使用overload resolution rules来决定哪个运算符(int
,uint
,{{1} },long
,ulong
,float
double
)是最好的。decimal
提供best conversion。char
击败int
,long
和float
,因为您可以implicitly convert double
加入这些类型,而不是回复。int
击败int
和uint
,因为......最好的转换规则就是这样。答案 3 :(得分:2)
这是如何发生的隐式转换(“char可以隐式转换为ushort,int,uint,long,ulong,float,double或decimal。”( {{ 3}} )。
最简单的复制形式可以在
找到int slash = +'/'; // 47
Char内部是一个结构。 “目的:这是表示Unicode字符的值类”( charMSDN ),并且可以隐式转换结构的原因是因为它实现了{ {3}}界面。
public struct Char : IComparable, IConvertible
具体来说,使用这段代码
/// <internalonly/>
int IConvertible.ToInt32(IFormatProvider provider) {
return Convert.ToInt32(m_value);
}
IConvertible
接口在代码
// IConvertible接口表示包含值的对象。这
//接口由System命名空间中的以下类型实现:
// Boolean,Char,SByte,Byte,Int16,UInt16,Int32,UInt32,Int64,UInt64,
// Single,Double,Decimal,DateTime,TimeSpan和String。
回顾struct的目的(作为代表unicode字符的值),很明显,语言中这种行为的意图是提供一种将值转换为支持的类型的方法。 IConvertible
继续陈述
//由System.XXX值类提供的IConvertible的实现 //简单地转发到适当的Value.ToXXX(YYY)方法(对。的描述) // Value类如下所示)。在Value.ToXXX(YYY)方法的情况下 //不存在(因为不支持特定的转换),
// IConvertible实现应该只抛出一个InvalidCastException。
明确说明不支持的转换会抛出异常。还明确指出,将字符转换为整数将给出该字符的整数值。
ToInt32(Char)方法返回一个32位有符号整数,表示value参数的UTF-16编码代码单元。的 char.csms referencesource 强>
总而言之,这种行为的推理似乎是不言而喻的。 char的整数值具有“UTF-16编码的代码单元”的含义。反斜杠的值为47.
由于存在值转换而且char
是内置数值类型,因此从加号隐式转换为整数是在编译时完成的。通过在小程序中重用上述简单示例可以看出这一点(linqpad可以测试这个)
void Main()
{
int slash = +'/';
Console.WriteLine(slash);
}
变为
IL_0000: ldc.i4.s 2F
IL_0002: stloc.0 // slash2
IL_0003: ldloc.0 // slash2
IL_0004: call System.Console.WriteLine
IL_0009: ret
将'/'
简单地转换为2F的十六进制值(十进制为47),然后从那里使用。
答案 4 :(得分:1)
+ '/'
为您提供字符“/”的UTF-16 (decimal) 47
字符代码,@ Guffa已经解释了原因。
答案 5 :(得分:1)
在c#中,char用单引号表示,即&#39; /&#39;在你的情况下,char前面的+运算符充当一元运算符,并要求编译器提供char&#39; /&#39;的UTF值。这是47。