繁体   English   中英

有没有其他方法来测试枚举位字段?

[英]Is there another way to test Enum bit fields?

将Enums与位字段一起使用时:

   enum  ReallyBigEnum  { FirstChoice = 0x01, AnotherOption = 0x02 }
   ReallyBigEnum  flag = ReallyBigEnum.FirstChoice | ReallyBigEnum.AnotherOption;

用于测试位的代码是:

   if( (flag & ReallyBigEnum.AnotherOption) == ReallyBigEnum.AnotherOption ) { ... }

由于需要重复被测试的位,这看起来很冗长且容易出错。

如果有某种方式可以说:

   if( flag.IsSet( ReallyBigEnum.AnotherOption ) ) { ... }

但是Enums不支持实例方法。 所以,我尝试了一个模板功能:

   class Enums
   {
      public static bool IsSet<T>( T flag, T bit ) { return (flag & bit) == bit; }
   }

但是测试位的代码看起来像这样:

   if( Enums.IsSet<ReallyBigEnum>( flag, ReallyBigEnum.AnotherOption ) ) { ... }

写的很多。 然后我试着缩短它:

   class Enums
   {
      public static bool IsSet( int flag, int bit ) { return (flag & bit) == bit; }
   }

但是你必须将每个值转换为它的基类型,如下所示:

   if( Enums.IsSet( (int)flag, (int)ReallyBigEnum.AnotherOption ) ) { ... }

这也是代码的痛苦并且失去了类型检查的好处。

可以编写相同的函数来使用'object'参数,但是必须测试对象类型和底层基类型。

所以,我坚持使用顶部的标准冗余方式。

有没有人对干净,简单的测试枚举位字段的方法有其他想法?

非常感谢。

高达.Net 3.5这是您唯一的选择。 在.Net 4.0中,枚举上有一个HasFlag方法。

if((flag & ReallyBigEnum.AnotherOption) != 0) { ... }

更新:

只有当你测试一个位时,上面显然才有效。 如果要测试多个位,则需要其他内容,具体取决于您是检查所有位还是任何位。

测试是否设置了任何一组位

对于这种情况,只需使用单比特版本的变体。

if((flag & (ReallyBigEnum.FirstOption | ReallyBigEnum.AnotherOption)) != 0) { ... }

测试是否设置了所有一组位

为了达到清晰度和可靠性,我建议创建一个包含所有位的常量。

const int ReallyBigEnum WickedAwesomeOptions = ReallyBigEnum.FirstOption | ReallyBigEnum.AnotherOption;
...
if (flag & WickedAwesomeOptions == WickedAwesomeOptions) { ... }

一些冗余仍然存在,但它不易碎或混乱,并且易于维护。

如果位组合适用广泛,那么您可以将它添加到枚举本身。

[Flags]
enum ReallyBigEnum
{
    FirstOption = 1,
    AnotherOption = 2,
    WickedAwesomeOptions = FirstOption | AnotherOption,
}
....
if (flag & ReallyBigEnum.WickedAwesomeOptions == ReallyBigEnum.WickedAwesomeOptions) { ... }
/// <summary>
/// Taken from https://stackoverflow.com/questions/9033/hidden-features-of-c/407325#407325
/// instead of doing (enum & value) == value you can now use enum.Has(value)
/// </summary>
/// <typeparam name="T">Type of enum</typeparam>
/// <param name="type">The enum value you want to test</param>
/// <param name="value">Flag Enum Value you're looking for</param>
/// <returns>True if the type has value bit set</returns>
public static bool Has<T>(this System.Enum type, T value)
{
   return (((int)(object)type & (int)(object)value) == (int)(object)value);
} 

这是我从上面的链接中获取的扩展方法

使用:

MyFlagEnum e = MyFlagEnum.First | MyFlagEnum.Second;
if(e.Has(MyFlagEnum.First))
{
   // Do stuff
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM