Skip to content
Variants and Type-Switching
step 1/5

Reading — step 1 of 5

Learn

~2 min readStrings, Procedural Types, Variants

Pascal's Variant type holds any value at runtime — number, string, array, etc. — and tracks its current type. Used heavily in COM/OLE and database code.

Basic variant

uses Variants;

var v: Variant;
begin
    v := 42;
    WriteLn(v);                    { 42 }

    v := 'hello';
    WriteLn(v);                    { hello }

    v := 3.14;
    WriteLn(v);                    { 3.14 }
end.

The variable changes type at runtime. Pascal handles conversions automatically:

v := 42;
WriteLn(v + 1);                    { 43 — int math }

v := '42';
WriteLn(v + 1);                    { 43 — auto-converts string to int }

Inspecting type

uses Variants;

case VarType(v) and varTypeMask of
    varInteger: WriteLn('int: ', integer(v));
    varString:  WriteLn('str: ', string(v));
    varDouble:  WriteLn('float: ', double(v));
    varBoolean: WriteLn('bool: ', boolean(v));
end;

Variant arrays

var arr: Variant;
begin
    arr := VarArrayCreate([0, 4], varInteger);
    arr[0] := 10;
    arr[1] := 20;
    arr[2] := 30;
    WriteLn(arr[2]);               { 30 }
end.

Used for COM Automation, dynamic database results — anywhere the schema isn't known at compile time.

Trade-offs

Pros:

  • No type juggling for the caller
  • Works well with dynamic data sources (DB, JSON, COM)
  • Scriptable interfaces

Cons:

  • ~10x slower than typed values (runtime dispatch)
  • Compiler can't catch type errors
  • Memory overhead per variable

For performance code: stick with typed values. For glue between dynamic systems: variants are the right tool.

Alternatives

  • TValue (RTTI-based) — newer Delphi/FPC; more typed than Variant
  • TJSONValue — JSON parsing libraries provide their own variant-like type
  • Discriminated unions via class hierarchy + is / as — type-safe at compile time, slower lookup

is and as for class types

Not Variants, but related — runtime type checks for objects:

if obj is TButton then
    WriteLn('it is a button');

var btn := obj as TButton;        { typed cast — raises EInvalidCast on mismatch }

Object Pascal's preferred way to handle polymorphism + occasional type-specific behavior.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…