2009-10-15 4 views
4

비트 플래그는 이해하기 :C#에서 플래그를 비교하는 방법? (2 부)

나는 약 thisthis 질문을 알고 난 대답을 이해하지 나는 심지어 내 좋은 친구에서이 article을 따라 조금 어렵습니다.

if (HttpContext.Current.Session["DebugSessionText"] != null) 
    { 
     showType = parDebug.Write2LogType.WARN | 
        parDebug.Write2LogType.ERROR | 
        parDebug.Write2LogType.INFO; 

     if (!chkInfo.Checked) 
      showType &= ~parDebug.Write2LogType.INFO; // remove INFOs   
     if (!chkError.Checked) 
      showType &= ~parDebug.Write2LogType.ERROR; // remove ERRORs 

     List<myDebugRow> list = 
      (List<myDebugRow>)HttpContext.Current.Session["DebugSessionText"]; 

     gv.DataSource = list.FindAll(x => x.Type == showType)); 
    } 
    gv.DataBind(); 

내가해야합니까 :

하지만 난 여전히 문이 안 열려도 그것을 필요 "축 폐선은"표준보다가 ...

는 난 할 노력하고있어이되는 List 객체를 필터링하면 사용자가 원하는 것을 얻을 수 있습니다 (INFO 오류 만 표시하고 예외 오류는 항상 표시되지만 WARNING 오류는 항상 표시됩니다).

이 작업을 직접 수행 할 수 있습니까 아니면 필터링해야합니다 LAMBDA 표현식을 사용하지 않고 수동으로?

도움 주셔서 감사합니다.

gv.DataSource = list.FindAll(x => 0 != (x.Type & showType))); 

당신이 오른쪽 유형 showType가 정확히되고 싶지 않기 때문에

+0

@balexandre : 아래에서 좋은 답변을 얻었습니다. 비트 연산자에 대한 자세한 내용은 http://stackoverflow.com/questions/1537713/what-is-the-second-meaning-of-a-single-ampersand-in-c/1537772#1537772 –

답변

10

x.Type == showType 

으로 만 모든 조건 (비트 플래그) 정확히 일치하는 항목을 얻을 것이다.

(x.Type & showType) != 0 

적어도 1 비트가 showType과 일치하는 모든 항목을 찾을 수 있습니다. 이는 아마도 원하는 것일 수 있습니다.

+0

정확히 ... ==는 모든 플래그가있는 경우에만 표시합니다. 도움과 설명을 제공해 주셔서 감사합니다. – balexandre

2
gv.DataSource = list.FindAll(x => x.Type == showType)); 

을해야 하는가? 수동으로 목록을 반복하고 비교를 수행하고 필요없는 것을 제거 할 수 있습니다. 그러나 이것이 우아한 해결책인지는 확실하지 않습니다.

+1

을 참조하십시오. C# 'int'(enum)에서'bool'으로 자동 변환하지 않습니다. –

9

이러한 작업이 혼란스럽고 솔직히 말해서 필자는 분명히 그런 다음 추상화 수준을 높이는 것을 고려합니다. 도우미 확장 메소드 몇 가지를 작성하십시오.

static WriteToLogType AddWarn(this WriteToLogType x) { return x | WriteToLogType.WARN; } 
static WriteToLogType ClearWarn(this WriteToLogType x) { return x & ~WriteToLogType.WARN; } 
static bool HasWarn(this WriteToLogType x) { return 0 != (x & WriteToLogType.WARN); } 
// same for Error, Info 
static bool HasExactly(this WriteToLogType x, WriteToLogType y) { return x == y; } 
static bool HasAny(this WriteToLogType x, WriteToLogType y) { return 0 != (x & y); } 
static bool HasAll(this WriteToLogType x, WriteToLogType y) { return y == (x & y); } 

그리고 이제 프로그램은 당신이 동의 희망

showType = WriteToLogType.None.AddWarn().AddInfo().AddError(); 
    if (!chkInfo.Checked) showType = showType.ClearInfo(); 
    if (!chkError.Checked) showType = showType.ClearError(); 
    List<myDebugRow> list = whatever; 
    gv.DataSource = list.FindAll(x => x.Type.HasAny(showType))); 

훨씬 더 분명 모든 비트 만지작보다가된다. 그러나 우리는 이것을 더 분명하게 할 수 있습니다.

showType = WriteToLogType.None.AddWarn(); 
    if (chkInfo.Checked) showType = showType.AddInfo(); 
    if (chkError.Checked) showType = showType.AddError(); 
    List<myDebugRow> list = whatever; 
    gv.DataSource = list.FindAll(x => x.Type.HasAny(showType))); 

플래그 묶음을 추가하고 제거하는 대신, 처음부터 추가하지 마십시오.

+0

나를 위해 "인형 용"을 넣는 +1 좋은 방법 :) – balexandre

관련 문제