我想在C#中编写一个函数,它将采用两个小的int值(范围0-3)并根据这些值返回Color
对象。问题在于,没有办法以编程方式确定两个值的颜色,它们是特定于LED类型的,必须进行硬编码。将两个值映射到一个对象
我能想到的最简单的方法将是一个巨大的(16例)if-else语句来检查每个值,但这似乎不是一个非常优雅的解决方案。有没有更好的方法来确定颜色?
我想在C#中编写一个函数,它将采用两个小的int值(范围0-3)并根据这些值返回Color
对象。问题在于,没有办法以编程方式确定两个值的颜色,它们是特定于LED类型的,必须进行硬编码。将两个值映射到一个对象
我能想到的最简单的方法将是一个巨大的(16例)if-else语句来检查每个值,但这似乎不是一个非常优雅的解决方案。有没有更好的方法来确定颜色?
那么Color对象的二维数组呢?
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];
作为使用if
/else
的一种稍微干净的替代方法,您可以将颜色值放在数组中,并将两个小的int值用作索引到数组中。
如果你想要去的面向对象的方法(或好或坏),你可以使用一个Tuple->颜色映射:在2 d阵列
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
,如果您尝试对两种颜色使用相同的元组。
不知道为什么这一个会得到downvoted。这是正确处理稀疏性的唯一解决方案,也是所有可扩展性最高的解决方案。您可以很容易地将其扩展到3变量的情况,并且您可以轻松地增加或减少变量范围(以及具有不同的范围)。根本不值得投降。 – drharris 2010-08-02 19:32:49
一堆if else
语句的首选方法是使用Switch
。你也可以使用一个enum
并指定对应于你的小整数INT值:
public enum ColorChoice
{
red = 01 //'01' instead of '1' to make clear your first digit is zero
blue = 02
green = 03
...etc...
]
这是如何解决处理两个输入参数以解决颜色问题的? – 2010-08-02 18:24:01
@kirk Woll - 我上次检查时,可以通过索引来调用Enum值。因此,输入“0,1”=>“1”=> ColorChoice.Red。与许多需要实际数学转换的解决方案相比,这实际上更容易理解(并因此保持)。 – AllenG 2010-08-02 18:29:26
您可以将整数转换为枚举。但是你将不得不在某个时刻进行数学转换。例如。你怎么做3,1 - >橙色。根据你的计划,它显然是橙色= 31,这需要数学(10 * x + y)。另外,你应该注意01实际上是一个八进制文字;它只是不会影响结果*在这里*。此外,C#枚举不能有任何字段或方法,因此您可能需要另一个ColorChoice-> Color映射。 – 2010-08-02 18:41:59
我投一个枚举的16种颜色
enum Color
{
red = 0,
blue = 1
}
public Color GetColor(int v1, int v2)
{
int colorValue = v1 << 8;
colorValue |= v2;
return (Color)colorValue;
}
使用乘法器是否是最可读的语法?我怀疑这会让很多程序员到山上去。 – 2010-08-02 18:25:14
我可以改变位移,但我认为这会将一个单独的程序员子集关闭。 – 2010-08-02 18:35:16
-1每个范围改为0-4时会发生什么?整个枚举的初始化都会发生变化,就像公式和所有事情一样。聪明,但不实际。 – drharris 2010-08-02 19:30:34
如何:
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];
}
}
如果走数组路由,多维或锯齿阵列肯定比手动实现乘法器好。唯一的缺点是检查映射是否正确,并且如果需要稀疏映射则为空。 – 2010-08-02 18:43:52
这真的是我所需要的,但我也很喜欢马修的建议。不幸的是我正在工作。NET 3.5不支持Tuple类。谢谢你们。 – Nate 2010-08-03 15:52:17