2011-02-11 2 views
10

의 내가이 열거 있다고 가정 해 봅시다 : 나는 간단하게 할 수있는 최초의 열거의 값을 통해어떻게 복잡한 열거 값의 캐릭터 라인 표현을 얻을 수

SomeType easyType = SomeType.Val1 | SomeType.Val2; 
SomeType complexType = SomeType.All; 

내가 루프를 원하는 경우

[Flags] 
public enum SomeType 
{  
    Val1 = 0, 
    Val2 = 1, 
    Val3 = 2, 
    Val4 = 4, 
    Val5 = 8, 
    Val6 = 16, 
    All = Val1 | Val2 | Val3 | Val4 | Val5 | Val6 
} 

일부 변수를 수행

foreach(string s in easyType.ToString().Split(',')) 
{ ... } 

을 그러나, 나는 물론이다 '복합 타입'나는 가치를 '전체'에 동일한 방법을 적용하려고하면 그것은 열거 형의 가능한 값 중 하나이기 때문에 유효합니다. 그러나 실제로 어떤 값이 SomeType인지 알 수있는 깔끔한 방법이 있습니까? 모두 생성 했습니까? 나는 그런 모든 값을 수동 루프를 만들 수 알고

if(complexType.HasFlag(ManualType.Val1) && ... 
+0

내가 문제가이 열거 안에'All'을 넣지해야한다는 것입니다 생각하는 이유, 예를 들면, 그건. 당신이 그것을'[Flags]'라고 표시했기 때문에 어떤 조합이라도 넣는 것은 나쁜 생각입니다. –

+0

그런 다음 SomeType을 사용할 때 열거 형의 적절한 조합을 사용하는 것을 항상 기억해야합니다. – IamDeveloper

+0

무의미한'SomeType' 대신 원래 enum을 게시 할 수 있습니까? –

답변

4
var result = string.Join(",", 
       Enum.GetValues(typeof(SomeType)) 
        .Cast<SomeType>() 
        .Where(v => complexType.HasFlag(v))); 

반복하는 것을 피하는 방법.

+1

끝에 "모두"가 포함되지 않습니까? 그것을 무시하는 특별한 경우가 필요합니까? – Justin

+0

@ Justin : 예, 가능합니다. 그러나 우리는 무엇을 할 수 있습니까? 그것이 "All"인지 확인하십시오. 그 이름이 "AllOptions"라면? 그래서 우리는이 "특별한 경우"를 다룰 수 없습니다. –

+0

내가 생각할 수있는 유일한 방법은 보이는 모든 이전 값의 비트 OR을 계속 실행 한 다음 새 비트가 포함되어 있지 않으면 값을 무시하는 것입니다. 그것은 순서에 의존 할 것이다. – Justin

0

은 아마 당신은 열거 값을 열거하고 테스트해야 하나 하나 : 당신은 확장을 작성할 수 있습니다

foreach (SomeType item in Enum.GetValues (typeof (SomeType)) 
{ 
    if ((complexType & item) == item) 
    { 
    //... 
    } 
} 
+0

그러나 나는 또한 모두를 시험 할 것이다. 내 상황에서는 괜찮아.하지만 SomeType.JustThree = Val1 | Val2 | Val3도 정의했으면 어떻게 될까? 최소한 중복됩니다. – IamDeveloper

0

여기, 그것을 할 한 가지 가능한 방법 대니 첸의 대답에 구축 :

public IEnumerable<T> GetFlags<T>(Predicate<int> hasFlag) 
{ 
    return GetEnumFlags<T>().Where(f => hasFlag(f)).Cast<T>(); 
} 

private IEnumerable<int> GetEnumFlags<T>() 
{ 
    return Enum.GetValues(typeof(T)).Cast<int>().Where(IsPowerOfTwoOrZero); 
} 

private bool IsPowerOfTwoOrZero(int v) 
{ 
    return ((v & (v-1)) == 0); 
} 

사용법 :이 int 스트 유형에 따라 열거 형을 위해 작동 할

void Main() 
{ 
    SomeType easyType = SomeType.Val1 | SomeType.Val2; 
    SomeType complexType = SomeType.All; 

    GetFlags<SomeType>(v => easyType.HasFlag((SomeType)v)); 
    GetFlags<SomeType>(v => complexType.HasFlag((SomeType)v)); 
} 

참고. long 등의 비슷한 방법을 만들 수 있습니다.

0

더 복잡한 수준 (임의의 요소 그룹, 색의 "어둠"등)을 가지고 있으며 그로 인해 어려움을 겪고있는 데이터를 나타 내기 위해 열거 형을 사용하는 경우 , 나는 enum이 잘못된 프로그래밍 구조를 사용하고 있다고 제안 할 것이다.

이러한 작업에 열거 형을 사용하면 항상 오류가 발생합니다. 열거 형에 새 색을 추가하면 "밝음"또는 "어두움"에도 추가해야합니다. 이로 인해 개발자는 원래의 문제와 마찬가지로 오류가 발생하기 쉬운 코드를 만들 수 있습니다. 그러나 일 수 있으며 밝은 지 여부를 나타내는 속성이있는 색상의 경우 class 또는 struct을 정의합니다. 그런 다음 더 단순한 언어 기능을 오용하려는 경우와 같이 가짜 결과를 내지 않는 방식으로 구현되는 명확하고 이해 가능한 기능을 제공하게됩니다.

Color is a struct ...

관련 문제