3

Which are differences between using a Variant array (Like shown here)

var
  VarArray : Variant;
begin
  VarArray := VarArrayCreate([0, 1], varInteger);
  VarArray[0] := 123;
  <...>
end;

instead of a common dynamic array?

var
  DynArray : array of Integer;
begin
  SetLength(DynArray, 1);
  DynArray[0] := 123;
  <...>
end;
Fabrizio
  • 7,603
  • 6
  • 44
  • 104
  • 1
    They are completely and utterly different things. Why do you want to use variant arrays? – David Heffernan Jul 01 '16 at 15:42
  • 1
    @DavidHeffernan: I always use dynamic arrays but I noticed that TDataSet.Locate accepts a Variant as KeyValues param. For this reason, I was wondering which were differences and if there were some reason why I should use Variant arrays instead of dynamic arrays. – Fabrizio Jul 01 '16 at 16:13
  • 3
    Use variant arrays if and only if you have to. That would be for COM compatibility. – David Heffernan Jul 01 '16 at 16:19

1 Answers1

11

Variants are a type that gets special handling from the compiler and the runtime. Under the hood, they are records of the type TVarRec. They can contain many different kinds of types internally, and can even be used to convert between some of these types. But they can also contain arrays of values, even arrays of other Variants, single- and multi-dimensional. That are Variant arrays. The System.Variants unit contains functions to define and handle such arrays.

Some more info on the Delphi Basics site.

Variants are typically used by Windows COM. Note that they can be pretty slow, especially Variant arrays with multiple dimensions. The number of types they can contain is limited.

Dynamic arrays are built-in types. They are normal arrays that can contain elements of any conceivable type, built-in or user defined. The difference with normal (static) arrays is that they can be instantiated, enlarged or shrunk dynamically (e.g. using SetLength), and their variables are pointers to the real array (which is allocated on the heap). Their lifetime is managed by the runtime.

Dynamic arrays are proper built-in types and far more general than Variants (and Variant arrays).

Delphi Basics also has more info on them.

Update

As Remy Lebeau commented, I should mention that a Variant array (and also an OleVariant array) is based on COM's SAFEARRAY structure, and thus can only be created with COM/OLE-compatible data types, even though Delphi's Variant can hold non-COM/OLE types.

Community
  • 1
  • 1
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
  • 2
    `Variant` is a built-in type. `OleVariant` is the COM variant type. When `Variant` was first added, it was the COM variant, but was later made a built-in type so it was not dependent on COM anymore, and `OleVariant` was added for compatibility with existing and new COM code. `Variant` and `OleVariant` are similar, but they do have functional differences. – Remy Lebeau Jul 01 '16 at 16:46
  • Variant may be a built-in type, but is internally compatible with COM, if you don't use it for Pascal-specific types like AnsiString etc. I have always seen it as an external non-Pascal type. – Rudy Velthuis Jul 01 '16 at 18:02
  • 3
    `Variant` can hold non-OLE data types, like `(Ansi|Unicode)String`, `TObject`, `TClass`, even user-defined types, and as such is not 100% compatible with COM without (potentially lossy) data conversions to OLE equivilents. `OleVariant`, on the other hand, is 100% compatible with COM as it is based on COM's own `VARIANT` structure, and all of Delphi's native COM interop uses `OleVariant` for `VARIANT` values. – Remy Lebeau Jul 01 '16 at 18:56
  • 1
    One thing you did not mention in your answer is that that a `Variant` array (and also an `OleVariant` array) is based on COM's [`SAFEARRAY`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221482.aspx) structure, and thus can only be created with COM/OLE-compatible data types, even though `Variant` can hold non-COM/OLE types. – Remy Lebeau Jul 01 '16 at 18:58