2012-07-15 88 views
3

我有了这个枚举标志:如何将枚举标志与Dictionary关键字进行比较?

[Flags()] 
public enum Levels 
{ 
    Beginner, Medium, Advanced, Master 
} 

我有一个叫做银行,在那里,这是一个Dictionary<Levels, ...>和层次上,你可以选择的可能选项属性

让我们去假设我的第一个KeyValuePair包含以下Key = Levels.Beginner | Levels.Medium | Levels. Advanced。因此,如果我输入字典Levels.Medium,则返回最后一个对象,因为Medium是可能的值。

public Worksheet LoadWorksheet(Levels level) 
{ 
    Worksheet worksheet = new Worksheet(this.Bank[level].Value, this.Bank[level].Key); 
    return worksheet; 
} 

但不幸的是,当我这样做时,会引发错误指出密钥不存在。我该如何配合钥匙?

回答

2

首先,我要指出的是,如果:

Levels keyA = Levels.Beginner | Levels.Medium | Levels. Advanced; 
Levels keyB = Levels.Medium; 

则:

Debug.Assert(keyA.GetHashCode() != keyB.GetHashCode()); 
Debug.Assert(keyA != keyB); 

当寻找在字典中的值,该字典第一个使用密钥的哈希值,以确定正确的桶,然后使用相等比较来标识桶中的右键。

如果散列值不相等,则不会找到密钥。如果键值不相等,则不会找到该值。

你可以看到,如果是位模式获得具有含Levels.Medium一个关键的所有条目存在于具有以下LINQ表达的关键:

var mediumEntries = Bank.Where(entry => 0 != ((int)entry.Key & (int)Levels.Medium)); 

或者,如@Ria指出,英寸网4您可以使用HasFlags成员:

var mediumEntries = Bank.Where(entry => entry.Key.HasFlag(Levels.Medium)); 

好点在另一个答案(@dasblinkenlight,@Ria)您的枚举值需要有非重叠这个工作位模式提出:

[Flags()]   
public enum Levels   
{   
    Beginner = 0x01, 
    Medium = 0x02, 
    Advanced = 0x04, 
    Master = 0x08 
} 
+0

我明白了,但在这种情况下,我该如何处理这个问题?在这种情况下,keyB在A中包含一个值,所以我试图匹配..但我不知道 – 2012-07-15 05:15:43

+0

@DarfZon我想要拿出一个示例。什么是KeyValuePair值的类型? – 2012-07-15 05:16:27

+0

这是一个列表其中T是一个自定义类 – 2012-07-15 05:18:53

0

以2的幂次定义枚举常量,即1,2,4,8等等。这意味着合并枚举常量的个人标志不重叠:

[Flags] 
public enum Levels 
{ 
    Beginner = 1, 
    Medium = 2, 
    Advanced = 4, 
    Master = 8 
} 

,你必须定义词典Key作为整数:Dictionary<int, ...>。和转换为int添加到字典时:使用.NET4使用HasFlag

if (this.Bank[level].Key.HasFlag(Levels.Advanced)) 
{ 
    // Do something 
} 

注意

if ((this.Bank[level].Key & Levels.Advanced) == Levels.Advanced) 
{ 
    // Do something 
} 

,如果:

Bank.Add((int) (Levels.Medium|Levels.Master), ...); 

然后比较关键枚举标志:

Dictionary.Key必须是唯一的。否则在尝试添加重复键时抛出ArgumentException。因此Flag枚举不建议用于Dictionary.Key。尝试存储一些地方。

+0

为什么键类型必须是'int'?这不就是说,OP将不得不始终将关键值转换回枚举类型?我认为在执行按位操作时将枚举值转换为int更好。 – 2012-07-15 05:45:47