C# 协议缓冲区中的uint转换

C# 协议缓冲区中的uint转换,c#,protocol-buffers,C#,Protocol Buffers,我在中定义了颜色消息,如下所示: message Color { fixed32 rgb = 1; } 我用C语言定义颜色如下: 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 { Rg

我在中定义了颜色消息,如下所示:

message Color {
    fixed32 rgb = 1;
}
我用C语言定义颜色如下:

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)
};
byte red=像素[4*索引+0];
字节绿色=像素[4*索引+1];
字节蓝色=像素[4*索引+2];
字节alpha=像素[4*索引+3];
颜色=新颜色
{

Rgb=(uint)((红色是的,这非常有效。这里发生的是
字节上的移位运算符(
)返回
int
。因为……原因。实际上,
字节上的几乎所有运算符都返回
int
-“或”(
)两个
字节
值之和也是一个
int

编译器不喜欢盲目地让您将
int
强制转换为
uint
,因此它只希望您确认您正在这样做,这就是您添加的
(uint)
所做的

因为我们知道您只填充前24位,所以我们知道该值始终为正,因此它将始终是可以安全地转换为无符号(
uint
)的正整数

如果填充所有32位,则最终值可能为负值,但默认情况下,C#编译器在“未选中”状态下工作模式,所以:它不在乎。它会很高兴地将负的
int
投射到
uint
-8
变成
4294967288
,例如。但是,作为命令行选项,“checked”可以启用模式-在这种情况下,您将得到一个
溢出异常
。为了避免这种情况,可以使用
未选中的
修饰符来告诉它显式不在乎,例如:

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

但是,几乎不需要使用
checked
。人们通常在关心溢出的地方添加偶尔的
checked
修饰符


最后总结:是的,你所拥有的一切都很好。

非常感谢。换句话说,如果我也将包含alpha值的颜色定义为
fixed32 rgba
,那么我最好添加以下
rgba=unchecked((uint)(红色@RaviJoshi),除非你特意启用“checked mode”,则无所谓;如果您希望代码以相同的方式工作,而不管是否有人启用“选中模式”在构建中,我当然明白了。我在这里有点困惑。在上面的例子中,你提到了
未检查的
,并解释了它在负数情况下很重要。但是,alpha是透明的,它永远不能是负数。我们事先就知道了。因此我真的需要使用“未检查的”?@Ravi作为两个补码二进制算术,如果最高有效位为1,则值为负。因此,如果alpha为128或更高,然后将其左移24位,则32位整数的最高有效位为1,为负。注意:如果不填充第4个字节,则根本不必担心它:无法获得负int32如果你只是将r,g和b组合成较低的24位,那么在你添加有意义的“alpha”之前,不需要取消选中。非常感谢。
int i = -8;
uint u = unchecked((uint)i);
unchecked
{
    int i = -8;
    uint u = (uint)i;
    // ...
}