views:

172

answers:

5

I was wondering if there was a more efficient (efficient as in simpler/cleaner code) way of making a case statement like the one below...

I have a dictionary. Its key type is an Enum and its value type is a bool. If the boolean is true, I want to change the color of a label on a form.

The variable names were changed for the example.

Dictionary<String, CustomType> testDict = new Dictionary<String, CustomType>();

//populate testDict here...

Dictionary<MyEnum, bool> enumInfo = testDict[someString].GetEnumInfo(); 
//GetEnumInfo is a function that iterates through a Dictionary<String, CustomType>
//and returns a Dictionary<MyEnum, bool>

            foreach (KeyValuePair<MyEnum, bool> kvp in enumInfo)
            {
                switch (kvp.Key)
                {
                    case MyEnum.Enum1:
                        if (someDictionary[kvp.Key] == true)
                        {
                            Label1.ForeColor = Color.LimeGreen;
                        }
                        else
                        {
                            Label1.ForeColor = Color.Red;
                        }
                        break;
                    case MyEnum.Enum2:
                       if (someDictionary[kvp.Key] == true)
                        {
                            Label2.ForeColor = Color.LimeGreen;
                        }
                        else
                        {
                            Label2.ForeColor = Color.Red;
                        }
                        break;
               }
           }

So far, MyEnum has 8 different values.. which means I have 8 different case statements.. I know there must be an easier way to do this, I just can't conceptualize it in my head.

If anyone could help, I'd greatly appreciate it. I love C# and I learn new things every day.. I absorb it like a sponge :)

-CP

+7  A: 

You could just switch the label, and then set the colors after the switch statement:

Label label = null;
switch (kvp.Key)
{
    case MyEnum.Enum1:
        label = Label1;
        break;
    case MyEnum.Enum2:
        label = Label2;
        break;
}

label.ForeColor = kvp.Value ? Color.LimeGreen : Color.Red;

Alternatively, you could have a Dictionary<MyEnum, Label>, and just lookup the label appropriately:

labelDictionary[kvp.Key].ForeColor = kvp.Value ? Color.LimeGreen : Color.Red;
Reed Copsey
Ah, thank you! I knew I could've used the ternary operator to save quite a bit of space.. I just hadn't thought of creating a dictionary containing the labels. Much appreciation! :)
C Patton
+2  A: 

Create a hash table that maps from your enum values to the label. Then you can just look up the label to change, rather than switch.

twk
+1  A: 

First, you may want to consolidate the body of the case statements into a function that accepts one or more parameters. This may be easier than duplicating content. @Reed's idea of selecting the right label instance in the switch statement is also a good idea, and if the logic only varies on this basis, be a better choice.

You can also use the ?: operator to simplify the decision logic.

For example:

switch (kvp.Key) 
            { 
                case MyEnum.Enum1: 
                    UpdateUI( Label1, someDictionary[kvp.Key] );
                    break; 
                case MyEnum.Enum2: 
                    UpdateUI( Label2, someDictionary[kvp.Key] );
                    break; 
                case MyEnum.Enum3: 
                    UpdateUI( Label3, someDictionary[kvp.Key] );
                    break; 
            }

public void UpdateUI( Label theLabel, bool whichOne )
{
     theLabel.ForeColor = whichOne ? Color.LimeGreen : Color.Red;
}
LBushkin
+2  A: 

Create a map between the enum and the label that needs to be changed based on that enum value. Then use the current enum value to get the corresponding label to update.

Dictionary<MyEnum,Label> labelMap = new Dictionary<MyEnum,Label>();
labelMap.Add( MyEnum.Enum1, Label1 );
...


foreach (KeyValuePair<MyEnum, bool> kvp in enumInfo)  
{  
    var label = labelMap[kvp.Key];
    label.ForeColor = kvp.Value ? Color.LimeGreen : Color.Red;
} 
tvanfosson
@tvanfosson: Completely off-topic, but congrats on breaking 100k!
Mark Rushakoff
Ah, thank you. This is pretty what I wanted. I appreciate it, and grats on 100k ;)
C Patton
@Mark, @CPatton Thanks.
tvanfosson
A: 

You can just put your cases in a dictionary:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ConsoleApplication3
{
class Program
{
    private enum MyEnum
    {
        shwan,
        dooo,
        sieven,
        sieven_haif,
        shwenty,
        shwenty_doo_haif,
        schfifty_faive
    }

    class EnumInfo
    {
        public MyEnum Enum;
        public bool State;

        public override bool  Equals(object obj)
        {
            EnumInfo ei = obj as EnumInfo;
            return this.Enum == ei.Enum && this.State == ei.State;
        }

        public override int GetHashCode()
        {
            return this.Enum.GetHashCode() ^ this.State.GetHashCode();
        }
    }

    private static IDictionary<EnumInfo, Color> EnumColorDict = new Dictionary<EnumInfo, Color>()
        {
            {new EnumInfo(){Enum=MyEnum.shwan, State=true},Color.LimeGreen},
            {new EnumInfo(){Enum=MyEnum.shwan, State=false},Color.Red},
            {new EnumInfo(){Enum=MyEnum.dooo, State=true},Color.LimeGreen},
            {new EnumInfo(){Enum=MyEnum.dooo, State=false},Color.Red}
        };

    static void Main(string[] args)
    {
        EnumInfo ei = new EnumInfo() { Enum = MyEnum.shwan, State = true };

        Color c = EnumColorDict[ei];
    }
}
}
MStodd
Hilarious enum names! That song's so old.. gives me flashbacks of an early last decade ;)I'm going with the accepted answer at the top as it reduced the lines of code from 80ish to 7 :)thanks a lot
C Patton
Well I made my answer into a program, and it's 55 lines, so if you subtract things that you already have in your program like: usings, MyEnum, Main function, it's probably not much longer, and I'd say it's more readable.Either way...
MStodd