这是如何发生的是隐式转换(“一个 char 可以隐式转换为 ushort、int、uint、long、ulong、float、double 或 decimal。”(@987654321 @)。
最简单的复制形式如下
int slash = +'/'; // 47
Char 内部是一个结构。 “目的:这是代表 Unicode 字符的值类”(char.csms referencesource),而结构体可以被隐式转换的原因是因为它实现了IConvertible界面。
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 编码代码单元。 Convert.ToInt32 Method (Char)MSDN
总而言之,这种行为的原因似乎是不言而喻的。 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),然后从那里使用。