C# 像binaryWriter.Write((字节)67)这样的东西是否涉及运行时强制转换?
由于没有后缀来表示字节文字,并且必须使用强制转换(或分配给字节变量),因此我使用以下代码来确保使用Write(byte)重载而不是Write(int): 我想知道编译后的代码是否会在运行时执行该转换,或者编译后的IL是否具有与字节文本后缀等效的内容,或者具体说明使用了哪个方法重载 我想知道编译后的代码是否真的会执行该转换 运行时 不,不会的。根据C语言规范第7.5.3.2章,对于两个重载C# 像binaryWriter.Write((字节)67)这样的东西是否涉及运行时强制转换?,c#,casting,C#,Casting,由于没有后缀来表示字节文字,并且必须使用强制转换(或分配给字节变量),因此我使用以下代码来确保使用Write(byte)重载而不是Write(int): 我想知道编译后的代码是否会在运行时执行该转换,或者编译后的IL是否具有与字节文本后缀等效的内容,或者具体说明使用了哪个方法重载 我想知道编译后的代码是否真的会执行该转换 运行时 不,不会的。根据C语言规范第7.5.3.2章,对于两个重载M(int n)和M(byte b),M(67)总是调用前者,因为67是int文本 如果编译后的IL具有相当于
M(int n)
和M(byte b)
,M(67)
总是调用前者,因为67
是int
文本
如果编译后的IL具有相当于
字节文字
不,没有像67L
/67UL
/67D
具体说明使用了方法的哪个重载
您可以像在问题中所做的那样使用显式转换(或将其分配给字节
变量),也可以像下面这样编写扩展方法来“重命名”原始函数:
public static class Ext
{
public static void WriteByte(this BinaryWriter writer, byte b)
{
writer.Write(b);
}
}
回答此类问题最简单的方法是查看生成的IL代码:
ldc.i4.s 67
callvirt instance void [mscorlib]System.IO.BinaryWriter::Write(unsigned int8)
首先,使用短格式(适用于-128到127之间的整数)将文本推送到堆栈中作为int32。如果只声明字节变量并使用它,就会发生这种情况。不要让“as int32”迷惑您——您无法将单个字节推送到堆栈,因此它总是至少推送4个字节(ldc.i4指令系列)
第二个调用正确的重载
现在,如果我们不强制转换到字节,会发生什么
ldc.i4.s 67
callvirt instance void [mscorlib]System.IO.BinaryWriter::Write(int32)
第一条指令完全相同,然后只调用另一个重载。
所以,您的问题的答案是:不执行强制转换,编译器只是专门声明要使用哪个重载。它只是选择重载。技术背景很深,让你进入处理器设计,你可以通过谷歌搜索“c整数推广”了解更多。适用于C语言,最好隐藏在C中,但原则是一样的。最明显的不隐藏的情况是必须使用强制转换将表达式的值存储回字节。。
ldc.i4.s 67
callvirt instance void [mscorlib]System.IO.BinaryWriter::Write(int32)