我正在尝试编写一个C#函数,该函数将获取两个小的int值(范围为0-3),并基于这些值返回一个Color对象。问题在于,无法通过编程方式确定颜色,因为它们是特定于LED类型的,并且必须硬编码。最简单的方法可能是使用一个庞大的if-else语句(16种情况)来检查每个值,但这似乎不是一个很优雅的解决方案。是否有更好的方法来确定颜色?
如果您想采用面向对象的方法(好或坏),您可以使用元组->颜色映射:
Dictionary<Tuple<int, int>, Color> d = new Dictionary<Tuple<int, int>, Color>()
{
{Tuple.Create(2, 1), Color.Red},
{Tuple.Create(1, 1), Color.Blue},
{Tuple.Create(1, 2), Color.Green}
};
相比二维数组,元组的一个优点是可以不用空值而实现稀疏存储。你还可以使用集合初始化器,而不必按索引顺序进行初始化。如果尝试将同一元组用于两种颜色,则在初始化时会明显抛出ArgumentException异常。
那么一个颜色对象的二维数组怎么样?
Color[,] colors = new[,] {
{ Color.FromArgb(1, 2, 3), Color.FromArgb(3, 4, 5), Color.FromArgb(6, 7, 8), Color.FromArgb(9, 10, 11) },
{ Color.FromArgb(21, 22, 23), Color.FromArgb(23, 24, 25), Color.FromArgb(26, 27, 28), Color.FromArgb(29, 30, 31) },
};
Color color = colors[index1, index2];
我为16种颜色投票一个枚举
enum Color
{
red = 0,
blue = 1
}
public Color GetColor(int v1, int v2)
{
int colorValue = v1 << 8;
colorValue |= v2;
return (Color)colorValue;
}
这样怎么样:
static Color GetColor(int c1, int c2)
{
if (c1 > 3 || c1 < 0 || c2 > 3 || c2 < 0)
throw new ArgumentOutOfRangeException();
var map = new Dictionary<string, Color>
{
{"00", Color.Black},
{"10", Color.Red},
{"20", Color.Blue},
// etc, etc...
{"11", Color.DimGray},
};
var key = c1.ToString() + c2.ToString();
return map[key];
}
你有这两个小整数值,它们结合在一起意味着某些东西(至少是颜色),这表明你可能需要定义一个结构体来封装它们。
这样做的好处是,你可以使用该结构体作为字典的键:Equals和GetHashCode方法应该已经足够工作。
以下是一个示例。由于你提到颜色无法计算,我在需要填充字典的地方留下了注释;你可以硬编码这个,但最好从文件或嵌入式资源中读取值。
编辑:更新了我的示例结构体为不可变的。
struct MyStruct
{
private byte _X;
private byte _Y;
public MyStruct(byte x, byte y)
{
_X = x;
_Y = y;
}
public byte X { get { return _X; } }
public byte Y { get { return _Y; } }
private static Dictionary<MyStruct, Color> _ColorMap;
static MyStruct()
{
_ColorMap = new Dictionary<MyStruct, Color>();
// read color mapping from somewhere...perhaps a file specific to the type of LED
}
public Color GetColor()
{
return _ColorMap[this];
}
}
public enum ColorChoice
{
red = 01 //'01' instead of '1' to make clear your first digit is zero
blue = 02
green = 03
...etc...
]