Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with an enumeration as a key in a Dictionary collection

Tags:

I have a scenario where I'm using a Dictionary to hold a list of transaction types that a certain system accepts. The key in the Dictionary is an enum field, the value is an int.

At some point in the system, we're going to want to do something like this:

sqlCommand.Parameters.AddWithValue("@param", LookupDictionary[argument.enumField]);

When we look up the field in the dictionary, we're going to get the correct integer value to feed to the database. I've thought about actually using the enum int value for this, but that's not exactly right. We're interacting with a system where we need to feed a magic number in to represent the kind of update we're doing.

The code above works just fine. I have an initializer method that adds the known types:

LookupDictionary = new Dictionary<mynamespace.myproject.myclass.enumType, int>();
LookupDictionary.Add(enumType.entry1, 4);
LookupDictionary.Add(enumType.entry2, 5);
LookupDictionary.Add(enumType.entry3, 6);

This code also works fine.

But up above, before I actually get in to using the LookupDictionary, I validate that the request being made is actually set to an enum value we support. That's LookupDictionary's main reason to be, it holds the valid ones (there are valid enum entries that this method doesn't work with).

This is the code that doesn't work: the system fails to recognize that the enums match. In the debugger, I can see that the entries list in LookupDictionary does show that it has the value for entry2 - it just calls it like that, entry2. The incoming enumField on the other hand has the full namespace; mynamespace.myproject.myclass.enumType.entry2 - I imagine this is why it doesn't see them as being the same.

if (!LookupDictionary.ContainsKey(argument.enumField))
{
    throw new InvalidOperationException("argument.enumField not valid in blahMethod.");
}

Did I mention that this is being passed across a WCF service? But I'm not using an auto-generated proxy ... both projects on both sides of the wire share the types as a project reference, and I build up my channel client in code.

Any ideas? Am I doing it wrong? Do Dictionaries with Enums as keys not work well? Is it a WCF thing?

Note: thanks for the suggestions regarding setting the enums up to contain the magic int. I wanted to set those in a configuration, however, as its possible that the "magic numbers" 4 5 and 6 might change down the road. So if I code them in to the enum as suggested:

public enum MyEnum
{
    MyValue1 = 4,
    MyValue2 = 5,
    MyValue3 = 6
}

I lose the ability to write a method that sets up the magic numbers in the future at run time; instead it would require a code change.

like image 517
Kyle Avatar asked Mar 05 '10 00:03

Kyle


People also ask

How do you enumerate a dictionary key?

To enumerate both keys and values, we can use the dictionary items() method. The items() method returns an object with the key-value pairs as tuples. The following example shows how we can use the items() method with the enumerate() function and access both the key and its corresponding value.

Can enum be a dict key Python?

Enumeration members are hashable, and that means we can use them as valid dictionary keys.

How do you avoid the given key was not present in the dictionary?

"The given key was not present in the dictionary." A better way would be: "The given key '" + key.

What is dictionary collection?

In C#, Dictionary is a generic collection which is generally used to store key/value pairs. The working of Dictionary is quite similar to the non-generic hashtable. The advantage of Dictionary is, it is generic type. Dictionary is defined under System. Collection.


1 Answers

Instead of using the enum as the key, use the integer representation of the enum.

For instance:

LookupDictionary = new Dictionary<int, int>();
LookupDictionary.Add((int)enumType.entry1, 4);
LookupDictionary.Add((int)enumType.entry2, 5);
LookupDictionary.Add((int)enumType.entry3, 6);

That way, you can use the same 'ContainsKey' method of the dictionary. I'm not sure this is much better performance than a List<int>

like image 196
Jim Schubert Avatar answered Sep 28 '22 06:09

Jim Schubert