在协议缓冲区中进行uint转换

时间:2017-11-23 04:34:09

标签: c# protocol-buffers

我在Protocol Buffers中定义了一条彩色信息,如下所示:

message Color {
    fixed32 rgb = 1;
}

我用C#语言定义Color如下:

byte red    = pixels[4 * index + 0];
byte green  = pixels[4 * index + 1];
byte blue   = pixels[4 * index + 2];
byte alpha  = pixels[4 * index + 3];
Color color = new Color
{
    Rgb = (uint)((red << 16) | (green << 8) | blue)
};

我担心以下操作是否有效:

Rgb = (uint)((red << 16) | (green << 8) | blue)

请注意,如果没有uint强制转换,程序会抛出编译错误。

1 个答案:

答案 0 :(得分:1)

是的,这完全有效。这里发生的事情是<<上的移位运算符(>> / byte)返回int。因为......原因。实际上,byte上的几乎所有运算符都返回int - 两个|值中的“或”(byte也< / em>一个int

编译器不喜欢盲目让你将int投射到uint,所以它只是要你承认你这样做,这是你添加的(uint)是什么。

由于我们知道您只填充前24位,因此我们知道该值始终为正,因此始终是一个正整数,可以安全地转换为无符号({ {1}})。

如果你填充所有32位,那么有机会最终值为负,但默认情况下 C#编译器在“未选中”模式下工作,所以:它并不关心。它会很乐意将uint投反对int。例如,uint变为-8。但是,作为命令行选项,可以启用“已选中”模式 - 在这种情况下,您将获得4294967288。为避免这种情况,可以使用OverflowException修饰符告诉显式无关,例如:

unchecked

int i = -8;
uint u = unchecked((uint)i);

但是,unchecked { int i = -8; uint u = (uint)i; // ... } 的这种用法几乎从未 。人们更常见的是在他们关心溢出的地方添加偶尔的unchecked修饰符。

总结:是的,你拥有的很好。