VB.NET和C#之间的二进制移位差异

时间:2011-11-16 12:01:26

标签: c# .net vb.net bit-manipulation vb.net-to-c#

我刚刚在翻译某些数据时发现了一个有趣的问题:

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)?

3 个答案:

答案 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还有另一个功能,可以使自动转换更具生存能力,默认情况下启用溢出检查。虽然这不适用于班次。