How to compare flags in C #? (part 2)

Bit flags are a little hard to understand :)

I know about this and this , and I understand the answers, and I even followed this article from my good friend.

But I still can’t understand when I need to β€œevolve” more than the standard ...

What I'm trying to do is:

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(); 

I need to filter out a List object, so I can get what the user wants (show only INFO errors, ERROR exceptions, but WARNing errors will always be displayed) ...

Is there a direct way to do this, or do I need to filter it manually without using the LAMBDA expression?

Thanks for the help.

+4
source share
3 answers

WITH

 x.Type == showType 

you will receive only those elements that meet all conditions (bit flags). WITH

 (x.Type & showType) != 0 

You will find all elements that have at least a one-bit match with showType, which you probably need.

+10
source

If you find that these operations are confusing - and to be honest, I certainly do - then consider raising the level of abstraction. Write yourself some helper extension methods.

 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); } 

And now your program becomes

  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))); 

I hope you will agree much more clearly than anything that is bit-twiddling. But we can make it even more clear.

  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))); 

Instead of adding a bunch of flags and then selecting them, just don't add them in the first place.

+9
source
 gv.DataSource = list.FindAll(x => x.Type == showType)); 

it should be

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

How do you not want Type to be exactly what showType is, right? You can manually iterate over the list and do a comparison and delete what you don't need, although I'm not sure if this is an elegant solution.

+2
source

All Articles