我怎么能知道项目是在枚举? [英] How can I know items is in the enum?

查看:181
本文介绍了我怎么能知道项目是在枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题的,我用的<$ C $ XOR运算符C>枚举与 [国旗] 属性如下:

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,我们当然应该用 | 运营商

To add an QueryFlag, of course we should use | operator.

flags |= QueryFlag.ByDate;

要删除一个,我有不同的方式与<一个href="http://stackoverflow.com/questions/3746291/other-method-for-iterating-an-enum/3746604#3746604">Dan涛的回答。我使用的:

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!

但在这里我得到了另外一个问题:我如何才能知道是否包含了一个项目?立足丹道的答案,我写了一个扩展:

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

我知道为什么它是假的原因,我怎么能提高呢?这是第一个问题。 第二:我想使。载通用于多个枚举 [国旗] 属性。

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搭配属性标记。但即使我删除此约束我得到一个编译错误,说操作符〜不能应用到类型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;
}

这将返回true,每当标志拥有的任意的(即至少有一个的)中所包含的标志标志,但我想你想的所有的。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆