Reputation: 2492
I am trying to write a function in C# that will take two small int values (range 0-3) and return a Color
object based on those values. The problem is that there is no way to programmatically determine the color from the two values, they are specific to a type of LED and must be hardcoded.
The simplest way I can think of would be a massive (16 cases) if-else statement that will check each value, but this doesn't seem like a very elegant solution. Is there a better way to determine the Color?
Upvotes: 3
Views: 1817
Reputation: 5967
I vote an enum for the 16 colors
enum Color
{
red = 0,
blue = 1
}
public Color GetColor(int v1, int v2)
{
int colorValue = v1 << 8;
colorValue |= v2;
return (Color)colorValue;
}
Upvotes: 0
Reputation: 10280
The fact that you have these two small integer values that combine together to mean something (at least a color) suggests to me that it might make sense for you to have a struct defined to encapsulate them.
The benefit of doing that is that you can use the struct as the key to a dictionary: the Equals and GetHashCode methods should already work adequately.
Below is an example. Since you mentioned that the colors cannot be calculated, I've left a comment where the dictionary needs to be populated; you could hard-code this, but ideally you'd read the values from a file or embedded resource.
EDIT: updated my example struct to be immutable.
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];
}
}
Upvotes: 0
Reputation: 284927
If you want to go the OO approach (for better or worse), you can use a Tuple->Color mapping:
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}
};
One advantage over a 2-d array is it can be sparse without nulls. You can also use a collection initializer without initializing in index order. This will throw an obvious ArgumentException
at initialization time if you try to use the same tuple for two colors.
Upvotes: 2
Reputation: 1588
How about:
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];
}
Upvotes: 0
Reputation: 77576
What about a two dimensional array of Color objects?
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];
Upvotes: 2
Reputation: 8190
The prefered method of avoid a bunch of if else
statements is to use Switch
. You could also use an enum
and assign int values which correspond to your small ints:
public enum ColorChoice
{
red = 01 //'01' instead of '1' to make clear your first digit is zero
blue = 02
green = 03
...etc...
]
Upvotes: -3
Reputation: 134207
As a slightly cleaner alternative to using if
/ else
, you could place the color values in an array, and use the two small int values as indexes into the array.
Upvotes: 1