如何知道项目在枚举中? [英] How can I know items is in the enum?
问题描述
在此问题中,我使用xor运算符枚举
与 [Flags]
属性如下:
In this question, I use xor operator between enum
with [Flags]
attribute as following:
[Flags]
enum QueryFlag
{
None = 0x1,
ByCustomer = 0x2,
ByProduct = 0x4,
ByDate = 0x8
}
QueryFlag flags = QueryFlag.ByCustomer | QueryFlag.ByProduct;
要添加QueryFlag,当然我们应该使用 |
operator。
To add an QueryFlag, of course we should use |
operator.
flags |= QueryFlag.ByDate;
要删除一个,我有一种不同的方式与丹涛的回答。我正在使用:
To remove one, I have a different way with Dan Tao's answer. I'm using:
flags ^= QueryFlag.ByProduct;
他正在使用:
flags &= ~QueryFlag.ByProduct;
显然他的答案是正确和容易理解的。我以为我犯了一个错误。但是经过深思,我得到了:
Obviously his answer is correct and easy to understand. I thought I made a mistake. But after a deep thought I got:
a,b a^b a&(~b)
0,0 0 0
0,1 1 0 //the difference
1,0 1 1
1,1 0 0
现在我知道我的错误。 ^
在您尝试删除不存在的项目时出错。
And now I knew my mistake. ^
is wrong when you try to remove one item which doesn't exist.
QueryFlag q = QueryFlag.ByCustomer | QueryFlag.ByDate;
//try to remove QueryFlag.ByProduct which doesn't exist in q
q ^ QueryFlag.ByProduct //equals to add ByProduct to q, wrong!
q & (~QueryFlag.ByProduct) // q isn't changed, remain the original value. correct!
但这里有另一个问题:我如何知道如果 q
包含一个项目?基于Dan Tao的答案我写了一个扩展名:
But here I got another question: how can I know if q
contains one item? Base on Dan Tao's answer I wrote an extension:
public static bool Contains(this QueryFlag flags, QueryFlag flag)
{
return (flags & (~flag)) != flags;
}
也就是说,如果标志在从标志中移除标志后没有更改,那么我们知道国旗不在国旗!以下情况似乎是正确的:
That is, if flags is not changed after removing flag from flags, we know flag is not in flags! It seems correct when:
(QueryFlag.ByProduct | QueryFlag.ByDate).Contains(QueryFlag.None) //false
(QueryFlag.ByProduct | QueryFlag.ByDate).Contains(QueryFlag.ByDate) //true
但实际上:
(QueryFlag.ByProduct | QueryFlag.ByDate).Contains(QueryFlag.ByDate | QueryFlag.ByCustomer) //true, but I suppose it's false
我知道为什么它是假的原因,我该如何改进?这是第一个问题。
第二个:我想使 .Contains
通用到更多枚举
与 [Flags]
属性
I know the reason why it's false, how can I improve it? It's the first question.
The second: I want to make the .Contains
generic to more enum
with [Flags]
attribute.
public static bool Contains<T>(this T flags, T flag) where T : Enum//with [Flags]
{
return (flags & (~flag)) != flags;
}
可能无法限制T标记的属性。但即使我删除了这个约束,我得到一个编译错误,说 operator〜不能应用于类型T
。为什么和如何解决?
Probably it's impossible to constrain T with attribute marked. But even I remove this constraint I get a compile error which says operator ~ can't be applied to type T
. Why and how to resolve?
推荐答案
您的错误在于这种方法:
Your error lies in this method:
public static bool Contains(this QueryFlag flags, QueryFlag flag)
{
return (flags & (~flag)) != flags;
}
每当 flags
具有标志
中包含的标志的任何(即至少一个),但我想你想要 all 。
This returns true whenever flags
has any (i.e. at least one) of the flags contained in flag
, but I think you want all.
它应该是:
public static bool Contains(this QueryFlag flags, QueryFlag flag)
{
return (flags & flag) == flag;
}
或者,您只需使用 Enum.HasFlag )
这样做。例如:
Alternatively, you can just use Enum.HasFlag()
which does exactly this. For example:
QueryFlag qf = ...;
if (qf.HasFlag(QueryFlag.ByCustomer))
// ...
这篇关于如何知道项目在枚举中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!