Sep*_*eph 11 .net c# 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)?
Chr*_*ris 11
根据http://msdn.microsoft.com/en-us/library/a1sway8w.aspx字节没有<<为它定义C#(只有int,uint,long和ulong.这意味着它将使用implciit转换为可以使用的类型,以便在执行位移之前将其转换为int.
http://msdn.microsoft.com/en-us/library/7haw1dex.aspx说VB定义了Bytes上的操作.为了防止溢出,它会在你的班次中使用一个掩码,使其处于适当的范围内,因此实际上在这种情况下根本不会移动.
至于为什么C#没有定义字节移位我无法告诉你.
要实际使其对于其他数据类型的行为相同,您需要将移位数屏蔽7(字节)或15(短信息)(请参阅第二个链接获取信息).
要在C#中应用相同的内容,您可以使用
static byte LeftShiftVBStyle(byte value, int count)
{
return (byte)(value << (count & 7));
}
Run Code Online (Sandbox Code Playgroud)
至于为什么VB采用这种方法....只是不同的语言,不同的规则(它是C#处理int /&31和long /&63的转换方式的自然延伸,公平).
克里斯已经指出它,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))
Run Code Online (Sandbox Code Playgroud)
和短操作员:
Dim result As Short = CShort(leftOperand << (rightOperand And 15))
Run Code Online (Sandbox Code Playgroud)
相应的C#操作是:
Dim result As Integer = CInt(leftOperand) << CInt(rightOperand)
Run Code Online (Sandbox Code Playgroud)
或者CLng()如果需要的话.C#代码隐含的是程序员总是必须将结果强制转换回所需的结果类型.这里有很多的关于做题从程序员不认为这是非常直观的.VB.NET还有另一个功能,可以使自动转换更具生存能力,默认情况下启用溢出检查.虽然这不适用于轮班.