C# 为什么颜色使用Int32而不是字节?

C# 为什么颜色使用Int32而不是字节?,c#,.net,types,C#,.net,Types,使用此示例: 从指定的8位颜色值(红色、, 绿色和蓝色)。alpha值隐式为255(完全不透明)。 尽管此方法允许为每种颜色传递32位值 组件,每个组件的值限制为8位 如果每个组件的值被限制为8位,那么为什么它们不使用字节而不是Int32 在更广泛的范围内,我发现人们非常普遍地使用Int32,即使Int16或Byte就足够了。使用Int32通常超过Int16、Byte等有什么特别的原因吗?我猜一些.NET语言不太支持Byte。也许它不符合CLS,我不记得了。如今,没有人再关心CLS合规性,但在

使用此示例:

从指定的8位颜色值(红色、, 绿色和蓝色)。alpha值隐式为255(完全不透明)。 尽管此方法允许为每种颜色传递32位值 组件,每个组件的值限制为8位

如果每个组件的值被限制为8位,那么为什么它们不使用
字节
而不是
Int32


在更广泛的范围内,我发现人们非常普遍地使用
Int32
,即使
Int16
Byte
就足够了。使用
Int32
通常超过
Int16
Byte
等有什么特别的原因吗?

我猜一些.NET语言不太支持Byte。也许它不符合CLS,我不记得了。如今,没有人再关心CLS合规性,但在1.0时代,这是一个重要的功能级别。还请注意,VB.NET不支持无符号类型,这是跨.NET语言对整数的不同支持的一个示例

对构造函数使用
int
特别奇怪,因为
A、R、G、B
属性是
byte

我认为这是一个API设计错误。


Color
struct通常不是特别漂亮。它不仅有ARGB值,还有一个
KnownColor
和一个名称。这个结构中塞满了许多顾虑。为了好玩,
Equals
方法有一个:
返回name.Equals(name)。当然,这总是正确的。这个结构看起来是匆忙完成的。从
Equals
方法可以看出,代码作者不知道字符串具有重载的相等运算符。
Color
的运算符等于刚才复制的15行。我想这个问题的真正答案是:实习生做到了


一般来说,
Int32
是首选,因为大多数算术运算扩展到32位,对于普通硬件来说,它是一个有效的整数宽度。较短的整数类型用于更特殊的用途


因为有人建议这样可以避免悲观情绪:我不明白这一点。加宽整数转换是隐式的,没有任何有意义的性能成本(通常没有)。

我认为没有什么好的理由。首先,我认为深入研究代码可以提供一些见解,但我所能找到的是,有一些检查可以确保
alpha
红色
绿色
蓝色
的值在[0..255]范围内,如果不在范围内,就会抛出异常。在内部,然后调用
MakeArgb
方法,该方法使用
byte

/// <summary>
///     [...]
///     Although this method allows a 32-bit value
///     to be passed for each component, the value of each
///     component is limited to 8 bits.
/// </summary>
public static Color FromArgb(int alpha, int red, int green, int blue)
{
    Color.CheckByte(alpha, "alpha");
    Color.CheckByte(red, "red");
    Color.CheckByte(green, "green");
    Color.CheckByte(blue, "blue");
    return new Color(Color.MakeArgb((byte)alpha, (byte)red, (byte)green, (byte)blue), Color.StateARGBValueValid, null, (KnownColor)0);
}

private static long MakeArgb(byte alpha, byte red, byte green, byte blue)
{
    return (long)((ulong)((int)red << 16 | (int)green << 8 | (int)blue | (int)alpha << 24) & (ulong)-1);
}

private static void CheckByte(int value, string name)
{
    if (value < 0 || value > 255)
    {
        throw new ArgumentException(SR.GetString("InvalidEx2BoundArgument",
                                    name,
                                    value,
                                    0,
                                    255));
    }
}
//
///     [...]
///尽管此方法允许使用32位值
///要为每个组件传递,每个组件的值
///组件限制为8位。
/// 
来自argb的公共静态颜色(整数alpha、整数红色、整数绿色、整数蓝色)
{
颜色。校验字节(alpha,“alpha”);
检查字节(红色,“红色”);
检查字节(绿色,“绿色”);
检查字节(蓝色,“蓝色”);
返回新颜色(Color.MakeArgb((字节)alpha,(字节)红色,(字节)绿色,(字节)蓝色),Color.StateARGBValueValid,null,(KnownColor)0);
}
私有静态长MakeArgb(字节alpha、字节red、字节green、字节blue)
{

return(long)((ulong)((int)red结构本身对R、G、B和A组件使用
byte
类型

我认为他们已经选择使用
int
作为参数类型,即使
byte
已经足够了,因为这样可以避免用户在将颜色的ARGB表示转换为
color
结构时返回到某个类型,正如名称所示。具体操作如下:

int argb = 0xffff0000; // Red
Color red = Color.FromArgb((argb & 0xff000000) >> 24, (argb & 0x00ff0000) >> 16, (argb & 0x0000ff00) >> 8, argb & 0x000000ff);
让编码器手动将每个字符转换为一个字节将使该行延长
“(byte)()”。Length*4
=32个字符


另外,当值大于255或小于0时,他们可以并且确实会引发
参数异常
,以正确地通知用户他们输入了错误的输入,而不是仅仅钳制值。也许他们在使用更高精度的
颜色
表示后忘记了规范化组件

我想,32位更适合典型的机器?我不确定,这只是一个注释…;)一般这个问题有一个完全不同的答案。我建议把它编辑掉。也许这会让你省去一点沮丧?@TGlatzer它会让你省去自己写一个,但是。可能FWIW字节的副本是兼容的,sbyte不是。@AlexK。好吧,也许
Color
的作者不知道:)(开玩笑。)
argb&0xff000000
转换为字节的值始终为零,您缺少一个移位。正确的方法是
(字节)(argb>>24)
。包括对字节的转换。@usr Oops,我的错。编辑了我的答案。