나는 열거 형이있다 :
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
가변 색상에서 파란색을 어떻게 제거합니까?
.ToString()
가치를 제공 합니다. 예를 들어 RED, BLUE, YELLOW
오히려 22
.
나는 열거 형이있다 :
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
가변 색상에서 파란색을 어떻게 제거합니까?
.ToString()
가치를 제공 합니다. 예를 들어 RED, BLUE, YELLOW
오히려 22
.
답변:
'BLUE' &
의 ~
(보완)로 해야합니다 .
보수 연산자는 기본적으로 주어진 데이터 유형에 대한 모든 비트를 반전 시키거나 '플립'합니다. 따라서 AND
연산자 ( &
)를 일부 값 (값을 'X'라고 함)과 하나 이상의 세트 비트의 보수 (그 비트 Q
와 보수를 호출하자 ~Q
)와 함께 사용하면 명령문 X & ~Q
은 설정된 비트를 지 웁니다. Q
from X
및 결과를 반환합니다.
따라서 BLUE
비트 를 제거하거나 지우 려면 다음 명령문을 사용하십시오.
colorsWithoutBlue = colors & ~Blah.BLUE
colors &= ~Blah.BLUE // This one removes the bit from 'colors' itself
다음과 같이 여러 비트를 지울 수 있습니다.
colorsWithoutBlueOrRed = colors & ~(Blah.BLUE | Blah.RED)
colors &= ~(Blah.BLUE | Blah.RED) // This one removes both bits from 'colors' itself
또는 교대로 ...
colorsWithoutBlueOrRed = colors & ~Blah.BLUE & ~Blah.RED
colors &= ~Blah.BLUE & ~Blah.RED // This one removes both bits from 'colors' itself
요약하면 다음과 같습니다.
X | Q
비트를 설정 Q
X & ~Q
비트를 지 웁니다 Q
~X
모든 비트를 뒤집거나 뒤집습니다. X
colors &= ~( Blah.BLUE | Blah.GREEN );
And not
그것...............................
Blah.RED | Blah.YELLOW ==
(Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;
이것은 나처럼 여기에서 우연히 발견 된 다른 사람들에게 유용 할 것이라고 생각했습니다.
값 == 0으로 설정 될 수있는 열거 형 값을 처리하는 방법에주의하십시오 (때로는 열거 형에 대해 알 수 없음 또는 유휴 상태를 유지하는 것이 도움이 될 수 있음). 이러한 비트 조작 작업에 의존 할 때 문제가 발생합니다.
또한 2의 다른 거듭 제곱의 조합 인 열거 형 값이있는 경우 (예 :
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
이러한 경우 다음과 같은 확장 방법이 유용 할 수 있습니다.
public static Colour UnSet(this Colour states, Colour state)
{
if ((int)states == 0)
return states;
if (states == state)
return Colour.None;
return states & ~state;
}
또한 결합 된 값을 처리하는 동등한 IsSet 메소드도 있습니다 (약간 해키 방식이지만)
public static bool IsSet(this Colour states, Colour state)
{
// By default if not OR'd
if (states == state)
return true;
// Combined: One or more bits need to be set
if( state == Colour.Orange )
return 0 != (int)(states & state);
// Non-combined: all bits need to be set
return (states & state) == state;
}
none
이나 unknown
또는 unset
값 == 0 항목이 많은 경우에 당신은 항상 당신은 레드, 블루와 그린은 당신이로 레드를 가지고가는 경우 특정 값이 기본 설정, 예를 있다고 가정 할 수 없기 때문에 좋은 것 기본값 (예를 들어 열거 형을 만들거나 사용자가이를 수정하지 않은 경우의 값)
1, 2, 4, 8
값으로 사용할 수 없습니까? 기본값이 필요한 경우 기본 생성자가 무엇입니까? 나는 가독성을 위해 가능한 한 명시 적으로 유지하고 싶습니다 . 값이 주어지지 않을 때 기본값으로 열거에 의존하는 것은 default(int)
( 0
)입니다. 어떤 개발자가 아마 알고있는 정보 임에도 불구하고 어쨌든 내 취향으로는 너무 열악합니다. 편집 : 아 잠깐, Unset = 0으로 만들면 무언가가 방해받지 Unset | Blue
않습니까?
Red & ~Red
0으로 끝나는 경우에는이 경우를 확인하고 명시 적으로 Unset
값을 할당하는 코드가 있어야 합니다)
플래그 열거를 단순화하고 배수를 피함으로써 읽는 것이 더 나을 수 있도록 비트 이동을 사용할 수 있습니다. (좋은 기사 에서 열거 형 깃발에 대한 대 쟁투 끝내기 )
[FLAG]
Enum Blah
{
RED = 1,
BLUE = 1 << 1,
GREEN = 1 << 2,
YELLOW = 1 << 3
}
또한 모든 비트를 지우려면
private static void ClearAllBits()
{
colors = colors & ~colors;
}