为什么"你好" + +' /' +"世界" ==" hello47world"?

时间:2015-08-01 17:48:37

标签: c# .net visual-studio

对于这个C#,a==true

bool a = "hello" +   '/' + "world" == "hello/world";

对于这个C#,b==true

bool b = "hello" + + '/' + "world" == "hello47world";

我想知道这是怎么回事,更重要的是,为什么C#语言架构师会选择这种行为?

6 个答案:

答案 0 :(得分:51)

第二个+正在将char转换为int,并将其添加到字符串中。 /的ASCII值为47,然后由另一个+运算符转换为字符串。

斜杠前的+运算符隐式将其强制转换为int。请参阅MSDN上的+ Operator,然后查看“一元加”。

  

对数字类型进行一元+运算的结果就是操作数的值。

我实际上通过查看+运营商实际呼叫的内容来解决这个问题。 (我认为这是ReSharper或VS 2015功能)

enter image description here

enter image description here

答案 1 :(得分:26)

那是因为您使用的是一元运算符+。它与一元运算符-类似,但它不会更改操作数的符号,因此它在此处唯一的作用是将字符'/'隐式转换为int

+'/'的值是/的字符代码,即47。

代码与:

相同
bool b = "hello" + (int)'/' + "world" == "hello47world";

答案 2 :(得分:16)

为什么,我听到你问,char是否专门针对运营商int operator +(int x)而不是many other fine unary + operators available之一?:

  • unary operator overload resolution rules首先要查看用户定义的一元运算符,但由于char没有任何一个,编译器会查看预定义一元+运营商。
  • 显然none of those也需要char,因此编译器使用overload resolution rules来决定哪个运算符(intuint,{{1} },longulongfloat double)是最好的。
  • 这些解决规则说要查看哪个是best function ...这几乎可以说明哪个参数类型从decimal提供best conversion
  • char击败intlongfloat,因为您可以implicitly convert double加入这些类型,而不是回复。
  • int击败intuint,因为......最好的转换规则就是这样。

答案 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。