Search code examples
delphisetenumeration

Delphi Set of Enumeration


I'm trying to filter my logging. If a log (or message) type is in the options, I want to send it to the log, otherwise exit.

The compilation fails on the "if not MessageType in..." line with:

"[dcc32 Error] uMain.pas(2424): E2015 Operator not applicable to this operand type"

I think it must be possible (and reasonably simple) based on the Include/Exclude functions, which I tried looking at but couldn't find anywhere (i.e. Include(MySet, llInfo); ).

My declaration are as follows:

type
  TLogLevel = (llDebug, llError, llWarn, llInfo, llException);
  TLogOptions = set of TLogLevel;

var
  FLogOptions: TLogOptions; 

procedure TfrmMain.Log(const s: String; MessageType: TLogLevel;
  DebugLevel: Integer; Filter: Boolean = True);
begin


  if not MessageType in FLogOptions then
    exit;

  mmoLog.Lines.Add(s);
end;

Solution

  • You need parentheses around the set operation because of operator precedence. The compiler is parsing it as if not MessageType, which is not a valid operation. If you put parentheses around the set test, the compiler can parse it correctly.

    if not (MessageType in FLogOptions) then
    

    This is a common issue, and is not specific to set types. For instance, you can get the same error with the following express as well.

    if not 1 = 2 and 2 = 3 then
    

    Adding parentheses around the two equality tests will correct the error.

    if not (1 = 2) and (2 = 3) then
    

    For more information, you can see the documentation for Operator Precedence