Switch/case with Color
Solution 1
Using a Dictionary is less code and more flexible as you can load it from a configuration file or the database. If you need to change the mapping, you won't have to rebuild your code.
Solution 2
I think in your case KnownColor enum will do the job, but you are limitted with the colors here
var c = KnownColor.Red;
switch (c)
{
case KnownColor.Red:
Console.WriteLine("true");
break;
default:
Console.WriteLine("False");
break;
}
Solution 3
I definitely think that using a dictionary is going to be the best approach.
However, if you really like switch statements, you could use Color.Name
and switch on that. Color.Name
will return the known name of the colour, if any, or the hexadecimal argb code for the colour if not.
Here's some sample code that demonstrates both approaches. I'm using a Lazy<>
to initialise the colour/action mapper to avoid any potental thread issues:
using System;
using System.Collections.Generic;
using System.Drawing;
namespace Demo
{
class Program
{
private void run()
{
test1(Color.Red);
test1(Color.Green);
test1(Color.FromArgb(0xea, 0x36, 0xbe));
test1(Color.FromArgb(0x24, 0x67, 0xc0));
test2(Color.Red);
test2(Color.Green);
test2(Color.FromArgb(0xea, 0x36, 0xbe));
test2(Color.FromArgb(0x24, 0x67, 0xc0));
}
private void test1(Color colour)
{
switch (colour.Name)
{
case "Red":
{
Console.WriteLine("Red");
break;
}
case "Green":
{
Console.WriteLine("Green");
break;
}
case "ffea36be":
{
Console.WriteLine("My custom colour");
break;
}
default:
{
Console.WriteLine("Unknown colour: " + colour.Name);
break;
}
}
}
private void test2(Color colour)
{
Action action;
if (_colourMapper.Value.TryGetValue(colour, out action))
action();
else
Console.WriteLine("Unknown colour: " + colour.Name);
}
private static Dictionary<Color, Action> createColourMapper()
{
var result = new Dictionary<Color, Action>();
result[Color.Red] = () => Console.WriteLine("Red");
result[Color.Green] = () => Console.WriteLine("Green");
result[Color.FromArgb(0xea, 0x36, 0xbe)] = () => Console.WriteLine("My custom colour");
return result;
}
private readonly Lazy<Dictionary<Color, Action>> _colourMapper = new Lazy<Dictionary<Color, Action>>(createColourMapper);
static void Main(string[] args)
{
new Program().run();
}
}
}
Comments
-
Sinatr almost 2 years
Quick and easy question:
How to make switch/case with lots of Colors.
What I can do is:
if(color == Color.Red) color = Color.Green; else { if(color == Color.Green) color = Color.Blue; else { // ... } }
or I can do a
Dictionary
with old/new color to replace them (in this specific example, there is no additional work needed apart from assigning a new color).or I can use tmp variable, so it become (but again, in this specific case):
Color tmp = Color.Transparent; // or whatever if(color == Color.Red) tmp = Color.Green; if(color == Color.Green) tmp = Color.Blue; //... color = tmp;
What I want is something like
switch(color) { case Color.Red: // ... break; case Color.Green: // ... break; case Color.Blue: // ... break; }
I found this interesting article, which I may decide to use.
Or I was thinking about something like
switch(color.ToArgb()) { case 129381038: // Color.Red?? how to put it here nicely? // ... }
What you guys think is better?
-
Sinatr over 10 yearsWell, I have
Color
and I needColor
at the end. Found how to convertKnownColor
toColor
. The question is how to convertColor
toKnownColor
? -
Sinatr over 10 yearsIs interesting, but typing all the colors without Intellisense help would be risky. And what to do with
SystemColor.ControlText
? -
Sinatr over 10 yearsWhen I say
Dictionary
I meanDictionary<Color, Color>
one. But I see whatDictionary
could also meanAction
, thanks for explaining that. And idea withColor.Name
when I can usecase "aarrggbb"
, wouldn't it be possible to define that as int? So I can use something likeswitch(color.ToArgb()) { case 0xaarrggbb: /* blablabla */ break; }
? -
Yaugen Vlasau over 10 yearsthe devil is as usual in details... your requirement to analyse the color is rather specific. so let try to imaging a set of names that could describe all possible colors. even if there is such a set of names each name will be the same informative as "case 129381038:" from your example. so... if there is no way to change requiremts to KnowColors, than the Dictionary approach seems to be the only possible
-
Sinatr over 10 yearsI could actually use your solution (I have so far only one abnormal color
SystemColors.ControlText
, but it is listed inKnownColors
), but I don't know how to initializeKnownColor
with knownColor
, what I am about to work with. Any ideas? -
Yaugen Vlasau over 10 yearshonestly - no. I cannt see a way convert color to known color. even Color.IKnownColor work only in case the color was created from a known color. so I have to reapeat it either task about color analisys or reqirements restriction to KnownColors or other set possible of colors.
-
Matthew Watson over 10 years@Sinatr Yes you could indeed use
Color.ToArgb()
instead ofColor.Name
, but then you wouldn't have any colour names in the switch cases, just numbers. But if that's what you want, then it's good to go! -
Sinatr over 10 yearsIt was useful to know =D
-
Sinatr over 10 yearsThe only questions is how to get
ARGB
numbers fromColor
as aconstant
. Makingconst int ColorRed = 0x00ff0000;
is a way toKnownColors
. Usingcolor.Name
and definingconst string ColorRed = "Red"
looks better than. Hmm.. seems I don't like either enough to get satisfied, sorry =( -
Matthew Watson over 10 years@Sinatr Aye, you can't get ARGB numbers from Color as constants. You'd have to define your own. But then you might as well use know colour strings instead.