我有这个枚举标志:
[Flags()]
public enum Levels
{
Beginner, Medium, Advanced, Master
}
我有一个名为Bank的属性,这是一个Dictionary<Levels, ...>
,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;
}
但不幸的是,当我这样做时,会向我发出错误,指出密钥不存在。如何匹配密钥呢?
答案 0 :(得分:2)
首先,我应该指出:if:
Levels keyA = Levels.Beginner | Levels.Medium | Levels. Advanced;
Levels keyB = Levels.Medium;
然后:
Debug.Assert(keyA.GetHashCode() != keyB.GetHashCode());
Debug.Assert(keyA != keyB);
在字典中查找值时,字典首先使用密钥的哈希值来确定正确的存储桶,然后使用相等比较来识别存储桶中的正确密钥。
如果哈希值不相等,则找不到密钥。如果键值不相等,则不会找到该值。
您可以通过查看具有以下LINQ表达式的密钥中是否存在位模式来获取包含Levels.Medium
的密钥的所有条目:
var mediumEntries = Bank.Where(entry => 0 != ((int)entry.Key & (int)Levels.Medium));
或者,正如@Ria指出的那样,在.Net 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
}
答案 1 :(得分:0)
以2的幂为单位定义枚举常量,即1,2,4,8等。这意味着组合枚举常量中的各个标志不重叠:
[Flags]
public enum Levels
{
Beginner = 1,
Medium = 2,
Advanced = 4,
Master = 8
}
并且必须将Dictionary Key定义为Integer:Dictionary<int, ...>
。并在添加到词典时转换为int
:
Bank.Add((int) (Levels.Medium|Levels.Master), ...);
然后将Key与枚举标志进行比较:
if ((this.Bank[level].Key & Levels.Advanced) == Levels.Advanced)
{
// Do something
}
如果使用.NET4,请使用HasFlag
if ( this.Bank[level].Key.HasFlag(Levels.Advanced) )
{
// Do something
}
注意:
Dictionary.Key
必须是唯一的。尝试添加重复键时,else会抛出ArgumentException
。这样就不会为Dictionary.Key
建议使用Flag枚举。尝试将其他地方存储在其他地方。