将枚举作为Dictionary集合中的键的问题

时间:2010-03-05 00:48:56

标签: c# wcf dictionary enums

我有一个场景,我使用Dictionary来保存某个系统接受的事务类型列表。 Dictionary中的键是一个枚举字段,值为int。

在系统的某个时刻,我们想要做这样的事情:

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

当我们在字典中查找字段时,我们将获得正确的整数值以提供给数据库。我已经考虑过为此实际使用enum int值,但这并不完全正确。我们正在与一个系统交互,我们需要提供一个神奇的数字来表示我们正在进行的更新。

上面的代码工作得很好。我有一个初始化方法,可以添加已知的类型:

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

此代码也可正常使用。

但是,在我真正开始使用LookupDictionary之前,我确认正在进行的请求实际上设置为我们支持的枚举值。这是LookupDictionary的主要原因,它包含有效的(有这个方法无法使用的有效枚举条目)。

这是不起作用的代码:系统无法识别枚举匹配。在调试器中,我可以看到LookupDictionary中的条目列表确实显示它具有entry2的值 - 它只是像那样调用它,entry2。另一方面,传入的enumField具有完整的命名空间; mynamespace.myproject.myclass.enumType.entry2 - 我想这就是为什么它看不出它们是一样的。

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

我是否提到过这是通过WCF服务传递的?但是我没有使用自动生成的代理......线路两端的两个项目共享类型作为项目引用,我在代码中构建了我的通道客户端。

有什么想法吗?我做错了吗?使用Enums作为键的字典不能很好地工作吗?这是WCF吗?

注意:感谢关于将枚举设置为包含magic int的建议。然而,我想在一个配置中设置它们,因为“魔术数字”4 5和6可能会改变。因此,如果我按照建议将它们编码到枚举中:

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

我失去了编写一个在将来运行时设置幻数的方法的能力;相反,它需要更改代码。

4 个答案:

答案 0 :(得分:3)

不使用枚举作为键,而是使用枚举的整数表示。

例如:

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

这样,您可以使用字典中相同的'ContainsKey'方法。我不确定这比List<int>

更好

答案 1 :(得分:1)

您根本不需要查找表:

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

// Sample usage
MyEnum firstEnum = MyEnum.MyValue1;
int intVal = (int)firstEnum;    // results in 4

// Enum Validation
bool valid = Enum.IsDefined(typeof(MyEnum), intVal);   // results in true

答案 2 :(得分:0)

您是否可以考虑将枚举显式地显示为int(或任何基础类型),然后将每个枚举的值设置为数据库值?您已经将枚举与数据库紧密耦合,因此关系将在C#(当前硬编码)或SQL中指定(可能是返回ID的proc以及可以解析为枚举的字符串。)

假设你的枚举是一个int ...

enum enumType {
    entry1 = 4,
    entry2 = 5,
    entry3 = 6
}

添加参数时,您只需将其转换为枚举的基础类型。

sqlCommand.Parameters.AddWithValue("@param", (int)argument.enumField);

答案 3 :(得分:0)

您可以使用语法

显式设置枚举值
enum ArgumentTypes {
    Arg1 = 1;
    Arg2 = 3;
    Arg3 = 5;
}

您无需在枚举中保持每个值的顺序,以使此语法有效。

要验证是否只使用了对该方法有效的参数,请尝试此示例代码。注意我建议在此上下文中使用ArgumentException而不是InvalidOperationException。

public void DoDbWork(ArgumentTypes argType, object otherParameter)
{
    if (argType == ArgumentTypes.Arg3) {
        throw new ArgumentException("Argument of value " + argType + " is not valid in this context", "argType");
    }

    // Handle db transaction here
}

将int值添加为参数:

cmd.Parameters.AddWithValue("@paramName", (int)argType);