FlagsAttribute FlagsAttribute FlagsAttribute FlagsAttribute Class

定义

指示可将枚举视为位域(即一组标志)。Indicates that an enumeration can be treated as a bit field; that is, a set of flags.

public ref class FlagsAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Enum, Inherited=false)]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class FlagsAttribute : Attribute
type FlagsAttribute = class
    inherit Attribute
Public Class FlagsAttribute
Inherits Attribute
继承
FlagsAttributeFlagsAttributeFlagsAttributeFlagsAttribute
属性

示例

下面的示例演示如何使用FlagsAttribute特性,并在显示效果ToString使用的方法FlagsAttributeEnum声明。The following example illustrates the use of the FlagsAttribute attribute and shows the effect on the ToString method of using FlagsAttribute on an Enum declaration.

using namespace System;

// Define an Enum without FlagsAttribute.
public enum class SingleHue : short
{
   None = 0,
   Black = 1,
   Red = 2,
   Green = 4,
   Blue = 8
};

// Define an Enum with FlagsAttribute.
[FlagsAttribute]
enum class MultiHue : short
{
   None = 0,
   Black = 1,
   Red = 2,
   Green = 4,
   Blue = 8
};

int main()
{
   // Display all possible combinations of values.
   Console::WriteLine(
        "All possible combinations of values without FlagsAttribute:");
   for (int val = 0; val <= 16; val++)
      Console::WriteLine("{0,3} - {1:G}", val, (SingleHue)val);
      
   Console::WriteLine(
        "\nAll possible combinations of values with FlagsAttribute:");
   
   // Display all combinations of values, and invalid values.
   for (int val = 0; val <= 16; val++ )
      Console::WriteLine("{0,3} - {1:G}", val, (MultiHue)val);
}
// The example displays the following output:
//       All possible combinations of values without FlagsAttribute:
//         0 - None
//         1 - Black
//         2 - Red
//         3 - 3
//         4 - Green
//         5 - 5
//         6 - 6
//         7 - 7
//         8 - Blue
//         9 - 9
//        10 - 10
//        11 - 11
//        12 - 12
//        13 - 13
//        14 - 14
//        15 - 15
//        16 - 16
//       
//       All possible combinations of values with FlagsAttribute:
//         0 - None
//         1 - Black
//         2 - Red
//         3 - Black, Red
//         4 - Green
//         5 - Black, Green
//         6 - Red, Green
//         7 - Black, Red, Green
//         8 - Blue
//         9 - Black, Blue
//        10 - Red, Blue
//        11 - Black, Red, Blue
//        12 - Green, Blue
//        13 - Black, Green, Blue
//        14 - Red, Green, Blue
//        15 - Black, Red, Green, Blue
//        16 - 16
using System;

class Example
{
   // Define an Enum without FlagsAttribute.
   enum SingleHue : short
   {
      None = 0,
      Black = 1,
      Red = 2,
      Green = 4,
      Blue = 8
   };

   // Define an Enum with FlagsAttribute.
   [FlagsAttribute] 
   enum MultiHue : short
   {
      None = 0,
      Black = 1,
      Red = 2,
      Green = 4,
      Blue = 8
   };

   static void Main( )
   {
      // Display all possible combinations of values.
      Console.WriteLine( 
           "All possible combinations of values without FlagsAttribute:");
      for(int val = 0; val <= 16; val++ )
         Console.WriteLine( "{0,3} - {1:G}", val, (SingleHue)val);

      // Display all combinations of values, and invalid values.
      Console.WriteLine( 
           "\nAll possible combinations of values with FlagsAttribute:");
      for( int val = 0; val <= 16; val++ )
         Console.WriteLine( "{0,3} - {1:G}", val, (MultiHue)val);
   } 
} 
// The example displays the following output:
//       All possible combinations of values without FlagsAttribute:
//         0 - None
//         1 - Black
//         2 - Red
//         3 - 3
//         4 - Green
//         5 - 5
//         6 - 6
//         7 - 7
//         8 - Blue
//         9 - 9
//        10 - 10
//        11 - 11
//        12 - 12
//        13 - 13
//        14 - 14
//        15 - 15
//        16 - 16
//       
//       All possible combinations of values with FlagsAttribute:
//         0 - None
//         1 - Black
//         2 - Red
//         3 - Black, Red
//         4 - Green
//         5 - Black, Green
//         6 - Red, Green
//         7 - Black, Red, Green
//         8 - Blue
//         9 - Black, Blue
//        10 - Red, Blue
//        11 - Black, Red, Blue
//        12 - Green, Blue
//        13 - Black, Green, Blue
//        14 - Red, Green, Blue
//        15 - Black, Red, Green, Blue
//        16 - 16
Module Example
   ' Define an Enum without FlagsAttribute.
   Enum SingleHue As Short
      None = 0
      Black = 1
      Red = 2
      Green = 4
      Blue = 8
   End Enum

   ' Define an Enum with FlagsAttribute.
   <FlagsAttribute> 
   Enum MultiHue As Short
      None = 0
      Black = 1
      Red = 2
      Green = 4
      Blue = 8
   End Enum

   Sub Main()
      ' Display all possible combinations of values.
      Console.WriteLine(
           "All possible combinations of values without FlagsAttribute:")
      For val As Integer = 0 To 16
         Console.WriteLine("{0,3} - {1:G}", val, CType(val, SingleHue))
     Next 
     Console.WriteLine()
     
     ' Display all combinations of values, and invalid values.
     Console.WriteLine( 
          "All possible combinations of values with FlagsAttribute:")
     For val As Integer = 0 To 16
        Console.WriteLine( "{0,3} - {1:G}", val, CType(val, MultiHue))
     Next 
   End Sub 
End Module 
' The example displays the following output:
'       All possible combinations of values without FlagsAttribute:
'         0 - None
'         1 - Black
'         2 - Red
'         3 - 3
'         4 - Green
'         5 - 5
'         6 - 6
'         7 - 7
'         8 - Blue
'         9 - 9
'        10 - 10
'        11 - 11
'        12 - 12
'        13 - 13
'        14 - 14
'        15 - 15
'        16 - 16
'       
'       All possible combinations of values with FlagsAttribute:
'         0 - None
'         1 - Black
'         2 - Red
'         3 - Black, Red
'         4 - Green
'         5 - Black, Green
'         6 - Red, Green
'         7 - Black, Red, Green
'         8 - Blue
'         9 - Black, Blue
'        10 - Red, Blue
'        11 - Black, Red, Blue
'        12 - Green, Blue
'        13 - Black, Green, Blue
'        14 - Red, Green, Blue
'        15 - Black, Red, Green, Blue
'        16 - 16

下面的示例定义两个颜色相关枚举SingleHueMultiHueThe following example defines two color-related enumerations, SingleHue and MultiHue. 后一种具有FlagsAttribute属性; 前者却没有。The latter has the FlagsAttribute attribute; the former does not. 范围的整数,其中包括不表示枚举类型的基础值的整数转换为枚举类型和显示其字符串表示形式时,示例将演示行为的差异。The example shows the difference in behavior when a range of integers, including integers that do not represent underlying values of the enumeration type, are cast to the enumeration type and their string representations displayed. 例如,请注意 3 不能表示为SingleHue值,因为 3 不是基础值的任何SingleHue成员,而FlagsAttribute属性使可能表示 3 一样MultiHue的值Black, RedFor example, note that 3 cannot be represented as a SingleHue value because 3 is not the underlying value of any SingleHue member, whereas the FlagsAttribute attribute makes it possible to represent 3 as a MultiHue value of Black, Red.

using namespace System;

[FlagsAttribute] enum class PhoneService
{
   None = 0,
   LandLine = 1,
   Cell = 2,
   Fax = 4,
   Internet = 8,
   Other = 16
};

void main()
{
   // Define three variables representing the types of phone service
   // in three households.
   PhoneService household1 = PhoneService::LandLine | PhoneService::Cell |
                             PhoneService::Internet;
   PhoneService household2 = PhoneService::None;
   PhoneService household3 = PhoneService::Cell | PhoneService::Internet;

   // Store the variables in an array for ease of access.
   array<PhoneService>^ households = { household1, household2, household3 };

   // Which households have no service?
   for (int ctr = 0; ctr < households->Length; ctr++)
      Console::WriteLine("Household {0} has phone service: {1}",
                         ctr + 1,
                         households[ctr] == PhoneService::None ?
                             "No" : "Yes");
   Console::WriteLine();

   // Which households have cell phone service?
   for (int ctr = 0; ctr < households->Length; ctr++)
      Console::WriteLine("Household {0} has cell phone service: {1}",
                         ctr + 1,
                         (households[ctr] & PhoneService::Cell) == PhoneService::Cell ?
                            "Yes" : "No");
   Console::WriteLine();

   // Which households have cell phones and land lines?
   PhoneService cellAndLand = PhoneService::Cell | PhoneService::LandLine;
   for (int ctr = 0; ctr < households->Length; ctr++)
      Console::WriteLine("Household {0} has cell and land line service: {1}",
                         ctr + 1,
                         (households[ctr] & cellAndLand) == cellAndLand ?
                            "Yes" : "No");
   Console::WriteLine();

   // List all types of service of each household?//
   for (int ctr = 0; ctr < households->Length; ctr++)
      Console::WriteLine("Household {0} has: {1:G}",
                         ctr + 1, households[ctr]);
   Console::WriteLine();
}
// The example displays the following output:
//    Household 1 has phone service: Yes
//    Household 2 has phone service: No
//    Household 3 has phone service: Yes
//
//    Household 1 has cell phone service: Yes
//    Household 2 has cell phone service: No
//    Household 3 has cell phone service: Yes
//
//    Household 1 has cell and land line service: Yes
//    Household 2 has cell and land line service: No
//    Household 3 has cell and land line service: No
//
//    Household 1 has: LandLine, Cell, Internet
//    Household 2 has: None
//    Household 3 has: Cell, Internet
using System;

[FlagsAttribute] public enum PhoneService
{
   None = 0,
   LandLine = 1,
   Cell = 2,
   Fax = 4,
   Internet = 8,
   Other = 16
}

public class Example
{
   public static void Main()
   {
      // Define three variables representing the types of phone service
      // in three households.
      var household1 = PhoneService.LandLine | PhoneService.Cell |
                       PhoneService.Internet;
      var household2 = PhoneService.None;
      var household3 = PhoneService.Cell | PhoneService.Internet;

      // Store the variables in an array for ease of access.
      PhoneService[] households = { household1, household2, household3 };

      // Which households have no service?
      for (int ctr = 0; ctr < households.Length; ctr++)
         Console.WriteLine("Household {0} has phone service: {1}",
                           ctr + 1,
                           households[ctr] == PhoneService.None ?
                               "No" : "Yes");
      Console.WriteLine();

      // Which households have cell phone service?
      for (int ctr = 0; ctr < households.Length; ctr++)
         Console.WriteLine("Household {0} has cell phone service: {1}",
                           ctr + 1,
                           (households[ctr] & PhoneService.Cell) == PhoneService.Cell ?
                              "Yes" : "No");
      Console.WriteLine();

      // Which households have cell phones and land lines?
      var cellAndLand = PhoneService.Cell | PhoneService.LandLine;
      for (int ctr = 0; ctr < households.Length; ctr++)
         Console.WriteLine("Household {0} has cell and land line service: {1}",
                           ctr + 1,
                           (households[ctr] & cellAndLand) == cellAndLand ?
                              "Yes" : "No");
      Console.WriteLine();

      // List all types of service of each household?//
      for (int ctr = 0; ctr < households.Length; ctr++)
         Console.WriteLine("Household {0} has: {1:G}",
                           ctr + 1, households[ctr]);
      Console.WriteLine();
   }
}
// The example displays the following output:
//    Household 1 has phone service: Yes
//    Household 2 has phone service: No
//    Household 3 has phone service: Yes
//
//    Household 1 has cell phone service: Yes
//    Household 2 has cell phone service: No
//    Household 3 has cell phone service: Yes
//
//    Household 1 has cell and land line service: Yes
//    Household 2 has cell and land line service: No
//    Household 3 has cell and land line service: No
//
//    Household 1 has: LandLine, Cell, Internet
//    Household 2 has: None
//    Household 3 has: Cell, Internet
<FlagsAttribute> Public Enum PhoneService As Integer
   None = 0
   LandLine = 1
   Cell = 2
   Fax = 4
   Internet = 8
   Other = 16
End Enum

Module Example
   Public Sub Main()
      ' Define three variables representing the types of phone service
      ' in three households.
      Dim household1 As PhoneService = PhoneService.LandLine Or
                                       PhoneService.Cell Or
                                       PhoneService.Internet
      Dim household2 As PhoneService = PhoneService.None
      Dim household3 As PhoneService = PhoneService.Cell Or
                                       PhoneService.Internet

      ' Store the variables in an array for ease of access.
      Dim households() As PhoneService = { household1, household2,
                                           household3 }

      ' Which households have no service?
      For ctr As Integer = 0 To households.Length - 1
         Console.WriteLine("Household {0} has phone service: {1}",
                           ctr + 1,
                           If(households(ctr) = PhoneService.None,
                              "No", "Yes"))
      Next
      Console.WriteLine()
      
      ' Which households have cell phone service?
      For ctr As Integer = 0 To households.Length - 1
         Console.WriteLine("Household {0} has cell phone service: {1}",
                           ctr + 1,
                           If((households(ctr) And PhoneService.Cell) = PhoneService.Cell,
                              "Yes", "No"))
      Next
      Console.WriteLine()
      
      ' Which households have cell phones and land lines?
      Dim cellAndLand As PhoneService = PhoneService.Cell Or PhoneService.LandLine
      For ctr As Integer = 0 To households.Length - 1
         Console.WriteLine("Household {0} has cell and land line service: {1}",
                           ctr + 1,
                           If((households(ctr) And cellAndLand) = cellAndLand,
                              "Yes", "No"))
      Next
      Console.WriteLine()
      
      ' List all types of service of each household?'
      For ctr As Integer = 0 To households.Length - 1
         Console.WriteLine("Household {0} has: {1:G}",
                           ctr + 1, households(ctr))
      Next
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'    Household 1 has phone service: Yes
'    Household 2 has phone service: No
'    Household 3 has phone service: Yes
'
'    Household 1 has cell phone service: Yes
'    Household 2 has cell phone service: No
'    Household 3 has cell phone service: Yes
'
'    Household 1 has cell and land line service: Yes
'    Household 2 has cell and land line service: No
'    Household 3 has cell and land line service: No
'
'    Household 1 has: LandLine, Cell, Internet
'    Household 2 has: None
'    Household 3 has: Cell, Internet

注解

位域一般用于结合使用,可能会出现的元素的列表而枚举常量一般用于互相排斥的元素的列表。Bit fields are generally used for lists of elements that might occur in combination, whereas enumeration constants are generally used for lists of mutually exclusive elements. 因此,位域旨在组合使用位或运算来生成未命名的值,而不是枚举的常量。Therefore, bit fields are designed to be combined with a bitwise OR operation to generate unnamed values, whereas enumerated constants are not. 语言差异在相比枚举常量的位域的使用。Languages vary in their use of bit fields compared to enumeration constants.

FlagsAttribute 特性Attributes of the FlagsAttribute

AttributeUsageAttribute 应用于此类,并将其Inherited属性指定falseAttributeUsageAttribute is applied to this class, and its Inherited property specifies false. 此属性只能应用于枚举。This attribute can only be applied to enumerations.

FlagsAttribute 和枚举的准则Guidelines for FlagsAttribute and Enum

  • 使用FlagsAttribute仅当对数字值执行按位运算 (AND、 OR、 异或) 是一个枚举的自定义属性。Use the FlagsAttribute custom attribute for an enumeration only if a bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a numeric value.

  • 定义中为 2 的幂,即 1、 2、 4、 8 和等等的枚举常量。Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. 这意味着在组合的枚举常量中的各个标志不会重叠。This means the individual flags in combined enumeration constants do not overlap.

  • 请考虑创建常用的标志组合一个枚举的常量。Consider creating an enumerated constant for commonly used flag combinations. 例如,如果有用于文件 I/O 操作的枚举,包含枚举的常量Read = 1Write = 2,请考虑创建的枚举的常量ReadWrite = Read OR Write,它结合ReadWrite标志。For example, if you have an enumeration used for file I/O operations that contains the enumerated constants Read = 1 and Write = 2, consider creating the enumerated constant ReadWrite = Read OR Write, which combines the Read and Write flags. 此外,用于组合标志的按位 OR 操作可能被视为一种高级的概念在某些情况下,不应要求对简单的任务。In addition, the bitwise OR operation used to combine the flags might be considered an advanced concept in some circumstances that should not be required for simple tasks.

  • 如果为标志枚举常量中定义为负数,因为很多标志位置可能会设置为 1,这可能会使您的代码令人困惑并鼓励编码错误,请格外小心。Use caution if you define a negative number as a flag enumerated constant because many flag positions might be set to 1, which might make your code confusing and encourage coding errors.

  • 测试是否设置了标志中的数字值的简便方法是执行按位 AND 运算之间的数字值和标志枚举的常量,它为不对应于该标志的零的数字值中的所有位都设置然后测试该操作的结果是否等于标志枚举常量。A convenient way to test whether a flag is set in a numeric value is to perform a bitwise AND operation between the numeric value and the flag enumerated constant, which sets all bits in the numeric value to zero that do not correspond to the flag, then test whether the result of that operation is equal to the flag enumerated constant.

  • 使用None用作枚举值为零的常量标志的名称。Use None as the name of the flag enumerated constant whose value is zero. 不能使用None按位运算中,若要测试一个标志,因为结果始终为零的枚举的常数。You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. 但是,你可以执行的逻辑不之间的数字值的按位、 比较和None枚举的常数,以确定是否设置在数值中的任何位。However, you can perform a logical, not a bitwise, comparison between the numeric value and the None enumerated constant to determine whether any bits in the numeric value are set.

    如果您创建的而不是标志枚举值枚举,则仍有必要创建None枚举的常数。If you create a value enumeration instead of a flags enumeration, it is still worthwhile to create a None enumerated constant. 原因是,默认情况下为该枚举所使用的内存初始化为零的公共语言运行时。The reason is that by default the memory used for the enumeration is initialized to zero by the common language runtime. 因此,如果未定义其值为零的常量,枚举将包含非法值时创建它。Consequently, if you do not define a constant whose value is zero, the enumeration will contain an illegal value when it is created.

    如果你的应用程序需要表示明显默认情况下,请考虑使用其值为零来表示默认值的枚举的常量。If there is an obvious default case your application needs to represent, consider using an enumerated constant whose value is zero to represent the default. 如果没有默认情况下,请考虑使用值为零的枚举的常数意味着不由任何其他枚举常量的用例。If there is no default case, consider using an enumerated constant whose value is zero that means the case that is not represented by any of the other enumerated constants.

  • 未定义的枚举值,只是为了反映该枚举本身的状态。Do not define an enumeration value solely to mirror the state of the enumeration itself. 例如,未定义的枚举的常量的只是表示枚举的结尾。For example, do not define an enumerated constant that merely marks the end of the enumeration. 如果您需要确定枚举的最后一个值,请显式检查值。If you need to determine the last value of the enumeration, check for that value explicitly. 此外,可以为第一个和最后一个枚举常量执行范围检查的范围内的所有值是否为有效。In addition, you can perform a range check for the first and last enumerated constant if all values within the range are valid.

  • 不要指定保留供将来使用的枚举的常量。Do not specify enumerated constants that are reserved for future use.

  • 在定义的方法或属性,它采用一个值作为一个枚举的常量时,请考虑验证值。When you define a method or property that takes an enumerated constant as a value, consider validating the value. 原因是,即使该数字的值未定义的枚举中,您可以强制转换为枚举类型的数字值。The reason is that you can cast a numeric value to the enumeration type even if that numeric value is not defined in the enumeration.

构造函数

FlagsAttribute() FlagsAttribute() FlagsAttribute() FlagsAttribute()

初始化 FlagsAttribute 类的新实例。Initializes a new instance of the FlagsAttribute class.

方法

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

返回一个值,该值指示此实例是否与指定的对象相等。Returns a value that indicates whether this instance is equal to a specified object.

(Inherited from Attribute)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

返回此实例的哈希代码。Returns the hash code for this instance.

(Inherited from Attribute)
GetType() GetType() GetType() GetType()

获取当前实例的 TypeGets the Type of the current instance.

(Inherited from Object)
IsDefaultAttribute() IsDefaultAttribute() IsDefaultAttribute() IsDefaultAttribute()

在派生类中重写时,指示此实例的值是否是派生类的默认值。When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class.

(Inherited from Attribute)
Match(Object) Match(Object) Match(Object) Match(Object)

当在派生类中重写时,返回一个指示此实例是否等于指定对象的值。When overridden in a derived class, returns a value that indicates whether this instance equals a specified object.

(Inherited from Attribute)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(Inherited from Object)
ToString() ToString() ToString() ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

(Inherited from Object)

显式界面实现

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) _Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) _Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) _Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

将一组名称映射为对应的一组调度标识符。Maps a set of names to a corresponding set of dispatch identifiers.

(Inherited from Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) _Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) _Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) _Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

检索对象的类型信息,然后可以使用该信息获取接口的类型信息。Retrieves the type information for an object, which can be used to get the type information for an interface.

(Inherited from Attribute)
_Attribute.GetTypeInfoCount(UInt32) _Attribute.GetTypeInfoCount(UInt32) _Attribute.GetTypeInfoCount(UInt32) _Attribute.GetTypeInfoCount(UInt32)

检索对象提供的类型信息接口的数量(0 或 1)。Retrieves the number of type information interfaces that an object provides (either 0 or 1).

(Inherited from Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) _Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) _Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) _Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供对某一对象公开的属性和方法的访问。Provides access to properties and methods exposed by an object.

(Inherited from Attribute)

属性

TypeId TypeId TypeId TypeId

在派生类中实现时,获取此 Attribute 的唯一标识符。When implemented in a derived class, gets a unique identifier for this Attribute.

(Inherited from Attribute)

适用于