System.FlagsAttribute 클래스

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

특성은 FlagsAttribute 열거형을 비트 필드, 즉 플래그 집합으로 처리할 수 있음을 나타냅니다.

비트 필드는 일반적으로 함께 발생할 수 있는 요소 목록에 사용되는 반면 열거형 상수는 일반적으로 상호 배타적 요소 목록에 사용됩니다. 따라서 비트 필드는 비트 OR 연산과 결합하여 명명되지 않은 값을 생성하도록 디자인된 반면 열거된 상수는 생성되지 않습니다. 언어는 열거형 상수에 비해 비트 필드 사용에 따라 다릅니다.

FlagsAttribute의 특성

AttributeUsageAttribute 가 이 클래스에 적용되고 해당 속성이 Inherited 지정됩니다 false. 이 특성은 열거형에만 적용할 수 있습니다.

FlagsAttribute 및 열거형에 대한 지침

  • FlagsAttribute 숫자 값에 대해 비트 연산(AND, OR, EXCLUSIVE OR)을 수행해야 하는 경우에만 열거형에 사용자 지정 특성을 사용합니다.

  • 열거형 상수(1, 2, 4, 8 등)를 2의 권한으로 정의합니다. 즉, 결합된 열거형 상수의 개별 플래그가 겹치지 않습니다.

  • 일반적으로 사용되는 플래그 조합에 대해 열거형 상수 만들기를 고려합니다. 예를 들어 열거된 상수가 포함된 파일 I/O 작업에 사용되는 열거형이 있는 경우 열거형 상 Read = 1 수와 Write = 2Write 플래그를 결합하는 열거형 상수 ReadWrite = Read OR Write만들기를 고려합니다Read. 또한 플래그를 결합하는 데 사용되는 비트 OR 연산은 간단한 작업에 필요하지 않은 경우에 고급 개념으로 간주될 수 있습니다.

  • 많은 플래그 위치가 1로 설정될 수 있으므로 음수를 플래그 열거 상수로 정의하면 코드가 혼동되고 코딩 오류가 발생할 수 있으므로 주의해야 합니다.

  • 플래그가 숫자 값에 설정되어 있는지 여부를 테스트하는 편리한 방법은 숫자 값과 플래그 열거 상수 간에 비트 AND 연산을 수행하는 것입니다. 이 연산은 숫자 값의 모든 비트를 플래그에 해당하지 않는 0으로 설정한 다음 해당 작업의 결과가 플래그 열거 상수와 같은지 여부를 테스트합니다.

  • 값이 0인 플래그 열거형 상수의 이름으로 사용합니다 None . 결과가 항상 0이므로 비트 AND 연산에서 열거형 상수로 플래그를 테스트할 수 없습니다 None . 그러나 숫자 값과 None 열거된 상수 간의 비트 비교가 아닌 논리적 비교를 수행하여 숫자 값의 비트가 설정되었는지 여부를 확인할 수 있습니다.

    플래그 열거형 대신 값 열거형을 만드는 경우에도 열거형 상수는 None 만드는 것이 좋습니다. 그 이유는 기본적으로 열거형에 사용되는 메모리가 공용 언어 런타임에 의해 0으로 초기화하기 때문입니다. 따라서 값이 0인 상수는 정의하지 않으면 열거형을 만들 때 잘못된 값이 포함됩니다.

    애플리케이션을 나타내는 필요한 명확한 기본 사례를 경우에 값이 기본값을 나타내는 0 인 열거형된 상수를 사용 하는 것이 좋습니다. 기본 사례가 없는 경우 값이 0인 열거형 상수는 열거된 다른 상수로 표현되지 않는 경우를 사용하는 것이 좋습니다.

  • 열거형 자체의 상태를 미러 위해서만 열거형 값을 정의하지 마세요. 예를 들어 열거형의 끝을 표시하는 열거형 상수만 정의하지 마세요. 열거형의 마지막 값을 결정해야 하는 경우 해당 값에 대해 명시적으로 검사. 또한 범위 내의 모든 값이 유효한 경우 첫 번째 및 마지막 열거형 상수에 대한 범위 검사 수행할 수 있습니다.

  • 나중에 사용하도록 예약된 열거형 상수를 지정하지 마세요.

  • 열거형 상수 값을 값으로 사용하는 메서드 또는 속성을 정의할 때 값의 유효성을 검사하는 것이 좋습니다. 그 이유는 해당 숫자 값이 열거형에 정의되지 않은 경우에도 숫자 값을 열거형 형식으로 캐스팅할 수 있기 때문입니다.

예제

다음 예제에서는 특성의 FlagsAttribute 사용을 보여 줍니다 및 선언에 사용 FlagsAttributeEnum 하는 ToString 방법에 미치는 영향을 보여 줍니다.

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.
    [Flags]
    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
open System

// Define an Enum without FlagsAttribute.
type SingleHue =
    | None = 0
    | Black = 1
    | Red = 2
    | Green = 4
    | Blue = 8

// Define an Enum with FlagsAttribute.
[<Flags>]
type MultiHue =
    | None = 0
    | Black = 1
    | Red = 2
    | Green = 4
    | Blue = 8

// Display all possible combinations of values.
printfn "All possible combinations of values without FlagsAttribute:"
for i = 0 to 16 do
    printfn $"{i,3} - {enum<SingleHue> i:G}"

// Display all combinations of values, and invalid values.
printfn "\nAll possible combinations of values with FlagsAttribute:"
for i = 0 to 16 do
    printfn $"{i,3} - {enum<MultiHue> i:G}"

// 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.
   <Flags()> 
   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

앞의 예제에서는 두 가지 색 관련 열거형과 SingleHueMultiHue. 후자에는 특성이 FlagsAttribute 있습니다. 전자는 그렇지 않습니다. 이 예제에서는 열거형 형식의 기본 값을 나타내지 않는 정수 등 정수 범위가 열거형 형식 및 해당 문자열 표현으로 캐스팅될 때의 동작 차이를 보여 줍니다. 예를 들어 3은 멤버의 SingleHue 기본 값이 아니므로 3을 값으로 SingleHue 나타낼 수 없는 반면 FlagsAttribute 특성은 3을 값Black, Red으로 MultiHue 나타낼 수 있습니다.

다음 예제에서는 특성을 사용하여 다른 열거형 FlagsAttribute 을 정의하고 비트 논리 및 같음 연산자를 사용하여 하나 이상의 비트 필드가 열거형 값에 설정되어 있는지 여부를 확인하는 방법을 보여 줍니다. 메서드를 Enum.HasFlag 사용하여 이 작업을 수행할 수도 있지만 이 예제에는 표시되지 않습니다.

using System;

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

public class Example1
{
    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
open System

[<Flags>]
type PhoneService =
    | None = 0
    | LandLine = 1
    | Cell = 2
    | Fax = 4
    | Internet = 8
    | Other = 16

// Define three variables representing the types of phone service
// in three households.
let household1 = 
    PhoneService.LandLine ||| PhoneService.Cell ||| PhoneService.Internet

let household2 = 
    PhoneService.None

let household3 = 
    PhoneService.Cell ||| PhoneService.Internet

// Store the variables in a list for ease of access.
let households =
    [ household1; household2; household3 ]

// Which households have no service?
for i = 0 to households.Length - 1 do
    printfn $"""Household {i + 1} has phone service: {if households[i] = PhoneService.None then "No" else "Yes"}"""
printfn ""

// Which households have cell phone service?
for i = 0 to households.Length - 1 do
    printfn $"""Household {i + 1} has cell phone service: {if households[i] &&& PhoneService.Cell = PhoneService.Cell then "Yes" else "No"}"""
printfn ""

// Which households have cell phones and land lines?
let cellAndLand = 
    PhoneService.Cell ||| PhoneService.LandLine

for i = 0 to households.Length - 1 do
    printfn $"""Household {i + 1} has cell and land line service: {if households[i] &&& cellAndLand = cellAndLand then "Yes" else "No"}"""
printfn ""

// List all types of service of each household?//
for i = 0 to households.Length - 1 do
    printfn $"Household {i + 1} has: {households[i]:G}"

// 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
<Flags()>
Public Enum PhoneService As Integer
   None = 0
   LandLine = 1
   Cell = 2
   Fax = 4
   Internet = 8
   Other = 16
End Enum

Module Example1
   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