我刚刚在翻译某些数据时发现了一个有趣的问题:
VB.NET:CByte(4) << 8
返回4
但C#:(byte)4 << 8
返回1024
即,为什么VB.NET:(CByte(4) << 8).GetType()
返回类型{Name = "Byte" FullName = "System.Byte"}
然而C#:((byte)4 << 8).GetType()
返回类型{Name = "Int32" FullName = "System.Int32"}
为什么这两个人对二进制移位的处理方式相同?接下来,是否有任何方法可以使C#位移与VB.NET相同(使VB.NET像C#一样执行CInt(_____) << 8
)?
答案 0 :(得分:11)
根据http://msdn.microsoft.com/en-us/library/a1sway8w.aspx字节没有&lt;&lt;在C#上定义了它(只有int,uint,long和ulong。这意味着它将使用implciit转换为它可以使用的类型,因此它在进行位移之前将其转换为int。
http://msdn.microsoft.com/en-us/library/7haw1dex.aspx说VB定义了Bytes上的操作。为了防止溢出,它会在你的班次中使用一个掩码使其处于适当的范围内,所以实际上在这种情况下它根本就没有任何变化。
至于为什么C#没有定义字节移位我无法告诉你。
要实际使其对于其他数据类型的行为相同,您需要将移位数屏蔽7(字节)或15(短信息)(参见第二个链接获取信息)。
答案 1 :(得分:6)
要在C#中应用相同的内容,您可以使用
static byte LeftShiftVBStyle(byte value, int count)
{
return (byte)(value << (count & 7));
}
为什么VB采用这种方法....只是不同的语言,不同的规则(它是C#处理int /&amp; 31和long /&amp; 63的转换方式的自然延伸,是公平的)。
答案 2 :(得分:6)
Chris已经确定了它,vb.net已经为Byte和Short类型定义了移位运算符,C#没有。 C#规范与C非常相似,也是OpCodes.Shl,Shr和Shr_Un的MSIL定义的良好匹配,它们只接受int32,int64和intptr操作数。因此,任何字节或短大小的操作数首先通过它们的隐式转换转换为int32。
这是vb.net编译器必须使用的限制,它需要生成额外的代码以使运算符的字节和短特定版本工作。字节运算符的实现方式如下:
Dim result As Byte = CByte(leftOperand << (rightOperand And 7))
和短操作员:
Dim result As Short = CShort(leftOperand << (rightOperand And 15))
相应的C#操作是:
Dim result As Integer = CInt(leftOperand) << CInt(rightOperand)
或CLng()(如果需要)。 C#代码隐含的是程序员总是必须将结果强制转换回所需的结果类型。有一些关于程序员的问题的很多,他们认为这些问题非常直观。 VB.NET还有另一个功能,可以使自动转换更具生存能力,默认情况下启用溢出检查。虽然这不适用于班次。