2010-08-02 41 views
3

我想在C#中编写一个函数,它将采用两个小的int值(范围0-3)并根据这些值返回Color对象。问题在于,没有办法以编程方式确定两个值的颜色,它们是特定于LED类型的,必须进行硬编码。将两个值映射到一个对象

我能想到的最简单的方法将是一个巨大的(16例)if-else语句来检查每个值,但这似乎不是一个非常优雅的解决方案。有没有更好的方法来确定颜色?

回答

2

那么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]; 
+0

如果走数组路由,多维或锯齿阵列肯定比手动实现乘法器好。唯一的缺点是检查映射是否正确,并且如果需要稀疏映射则为空。 – 2010-08-02 18:43:52

+0

这真的是我所需要的,但我也很喜欢马修的建议。不幸的是我正在工作。NET 3.5不支持Tuple类。谢谢你们。 – Nate 2010-08-03 15:52:17

1

作为使用if/else的一种稍微干净的替代方法,您可以将颜色值放在数组中,并将两个小的int值用作索引到数组中。

2

如果你想要去的面向对象的方法(或好或坏),你可以使用一个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,如果您尝试对两种颜色使用相同的元组。

+0

不知道为什么这一个会得到downvoted。这是正确处理稀疏性的唯一解决方案,也是所有可扩展性最高的解决方案。您可以很容易地将其扩展到3变量的情况,并且您可以轻松地增加或减少变量范围(以及具有不同的范围)。根本不值得投降。 – drharris 2010-08-02 19:32:49

-3
避免

一堆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... 
] 
+2

这是如何解决处理两个输入参数以解决颜色问题的? – 2010-08-02 18:24:01

+0

@kirk Woll - 我上次检查时,可以通过索引来调用Enum值。因此,输入“0,1”=>“1”=> ColorChoice.Red。与许多需要实际数学转换的解决方案相比,这实际上更容易理解(并因此保持)。 – AllenG 2010-08-02 18:29:26

+0

您可以将整数转换为枚举。但是你将不得不在某个时刻进行数学转换。例如。你怎么做3,1 - >橙色。根据你的计划,它显然是橙色= 31,这需要数学(10 * x + y)。另外,你应该注意01实际上是一个八进制文字;它只是不会影响结果*在这里*。此外,C#枚举不能有任何字段或方法,因此您可能需要另一个ColorChoice-> Color映射。 – 2010-08-02 18:41:59

0

我投一个枚举的16种颜色

enum Color 
{ 
    red = 0, 
    blue = 1 
} 

public Color GetColor(int v1, int v2) 
{ 
    int colorValue = v1 << 8; 
    colorValue |= v2; 
    return (Color)colorValue; 
} 
+0

使用乘法器是否是最可读的语法?我怀疑这会让很多程序员到山上去。 – 2010-08-02 18:25:14

+0

我可以改变位移,但我认为这会将一个单独的程序员子集关闭。 – 2010-08-02 18:35:16

+0

-1每个范围改为0-4时会发生什么?整个枚举的初始化都会发生变化,就像公式和所有事情一样。聪明,但不实际。 – drharris 2010-08-02 19:30:34

0

如何:

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]; 
} 
0

的事实上,你有这两个小的整数值结合在一起意味着什么(至少是一种颜色)暗示我可能有意义,你有一个定义的结构来封装米

这样做的好处是您可以使用结构作为字典的关键字: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]; 
    } 
} 
相关问题