Comparing Variants

I hate Variants, did I say that before? They just make everything more complex than necessary.

Did you ever try to compare two variants? E.g. you have got one that contains an empty string (”) and another that contains a date. Now you want to know whether they are equal or not. Simple?

  v1 := '';
  v2 := EncodeDate(2014,07,01);
  if v1 <> v2 then
    WriteLn('not equal')
  else
    WriteLn('equal');

Not so. The code above raised a EVariantConversionError exception because it could not convert an empty string into a date.

Let me introduce you to two Delphi RTL functions from Variants.pas:

VarSameValue and VarCompareValue.

(I bet you didn’t know about them, did you?)

Assuming these functions work as described, the above must be written like this:

  v1 := '';
  v2 := EncodeDate(2014,07,01);
  if not VarSameValue(v1, v2) then
    WriteLn('not equal')
  else
    WriteLn('equal');

Unfortunately they fail as well with exactly the same error. So all that’s left is implementing it myself.

function VarIsSame(_A, _B: Variant): Boolean;
var
  LA, LB: TVarData;
begin
  LA := FindVarData(_A)^;
  LB := FindVarData(_B)^;
  if LA.VType <> LB.VType then
    Result := False
  else
    Result := (_A = _B);
end;

Note that this too might not do what you expect:

  VarIsSame('3', 3);

will return false! That’s why it’s called VarIsSame rather than VarIsSameValue. It doesn’t try to convert variants of different types, it just checks whether they are the same.
For my use case this is exactly what I need.

Did I mention that I hate Variants?