C#:获取按位枚举中的最小值键
我有这样的枚举C#:获取按位枚举中的最小值键,c#,enums,bitwise-operators,C#,Enums,Bitwise Operators,我有这样的枚举 [Flags] public enum Key { None = 0, A = 1, B = 2, C = 4 } 我有以下几点 Key k1 = Key.A | Key.B | Key.C; 我想得到k1中具有最小值的键。我该怎么做 例如: Key k1 = Key.A | Key.B | Key.C; // I want a Key k2 = Key.B | Key.C; // I want b Key k3 = Key.A | Key.C; // I
[Flags]
public enum Key
{
None = 0,
A = 1,
B = 2,
C = 4
}
我有以下几点
Key k1 = Key.A | Key.B | Key.C;
我想得到k1中具有最小值的键。我该怎么做
例如:
Key k1 = Key.A | Key.B | Key.C; // I want a
Key k2 = Key.B | Key.C; // I want b
Key k3 = Key.A | Key.C; // I want a
如果枚举中只有3个值,那么最快和最简单的方法可能是逐个检查它们。但是,对于一般解决方案,您可能希望尝试将
k1
的值转换为整数,找到将其除以的最大2次方,然后将其转换回Keys enum值
Keys key=Keys.b | Keys.c;
var lower=Enum.GetValues(typeof(Keys))
第()类
.其中(x=>(x&键)!=0)
.OrderBy(x=>x)
.DefaultIfEmpty((键)0);
控制台写入线(最低);
您可以使用一些技巧:
Key key = Key.B | Key.C;
Key lowest = (Key)((int)key & -(int)key);
需要是一个迭代实现,在其中测试位。我会这样做
unsigned int k = (unsigned int) k1;
int pos = -1;
while (k) {
pos++;
if (k & 0x1) break;
k >>= 1;
}
Keys lowestKey = 0;
if (pos >= 0) lowestKey = 0x1 << pos;
unsigned int k=(unsigned int)k1;
int pos=-1;
while(k){
pos++;
如果(k&0x1)中断;
k>>=1;
}
Keys lowerstkey=0;
如果(pos>=0)lowestKey=0x1您最初发布的代码没有意义:a+b+c没有类型名前缀,因此它们不会引用它们似乎要引用的枚举名
此外,如果使用按位AND组合标志,结果将在所有参数中包含所有打开的标志-在本例中为“无”。Keys key=Keys.b | Keys.c;
Keys key = Keys.b | Keys.c;
var lowest = Enum.GetValues(typeof(Keys))
.Cast<Keys>()
.OrderBy(x => x)
.FirstOrDefault(x => key.HasFlag(x));
var lower=Enum.GetValues(typeof(Keys))
.Cast()
.OrderBy(x=>x)
.FirstOrDefault(x=>key.HasFlag(x));
LINQ方法的.NET 4.0-ish版本稍微更有效。这是你的家庭作业,不是吗?另外,如果这是按位枚举,它需要一个Flags属性,通常一个None值=0,而你在构建集合时不需要按位和按位标记,你或他们。@Gjorgji和@NickLarsen:我刚刚意识到并解决了这个问题,除非应用了Flags属性,否则就没有意义了。@David:我个人认为它几乎不可读。这是一个有趣的奇怪现象,但我希望没有人真的在生产代码中使用它!我更喜欢使用LINQ方法之一。如果有人真的用这个,我希望他们至少在评论中解释一下它在做什么。是的,这需要一点时间,但我可以向你保证它是最快的,而且非常简洁。这当然是可读性和效率的折衷。话虽如此,我可能会把这样的东西放进去,然后忘记我后来做了什么。不过,如果你只是简单地谈论极客因素,那就很酷了。我想你应该在第一个之前添加类似.DefaultIfEmpty((Keys)0)
的内容,这样当key为0时就不会抛出异常。
Keys key = Keys.b | Keys.c;
var lowest = Enum.GetValues(typeof(Keys))
.Cast<Keys>()
.OrderBy(x => x)
.FirstOrDefault(x => key.HasFlag(x));