A: An array of const is in fact an open array of TVarRec (a predeclared Delphi type you can look up in the online help). So the following is the general battle plan:
procedure AddStuff( Const A: Array of Const );
Var i: Integer;
Begin
For i:= Low(A) to High(A) Do
With A[i] Do
Case VType of
vtExtended: Begin
{ add real number, all real formats
are converted to extended automatically }
End;
vtInteger: Begin
{ add integer number, all integer
formats are converted to LongInt automatically }
End;
vtObject: Begin
If VObject Is DArray Then
With DArray(
VObject ) Do Begin
{ add array of doubles }
End
Else If VObject Is IArray
Then
With IArray(
VObject ) Do Begin
{ add array of integers }
End;
End;
End; { Case }
End; { AddStuff }
For further information see "open arrays" in the on-line help.
Here is a bit more from Steve:
An "array of const" is an array of values passed as const. Internally, these are represented by TVarRec structures. The brackets are simply to delimit the array. Arrays of const give you the ability to send a variable number of parameters to a routine in a type-safe manner. Here's an example:
type
TVarRec = record
Data: record case Integer of
0: (L: LongInt);
1: (B: Boolean);
2: (C: Char);
3: (E: ^Extended);
4: (S: ^String);
5: (P: Pointer);
6: (X: PChar);
7: (O: TObject);
end;
Tag: Byte;
Stuff: array[0..2] of Byte;
end;
function PtrToStr(P: Pointer): String;
const
HexChar: array[0..15] of Char = '0123456789ABCDEF';
function HexByte(B: Byte): String;
begin
Result := HexChar[B shr 4] + HexChar[B and 15];
end;
function HexWord(W: Word): String;
begin
Result := HexByte(Hi(W)) + HexByte(Lo(W));
end;
begin
Result := HexWord(HiWord(LongInt(P))) + ':' + HexWord(LoWord(LongInt(P)));
end;
procedure Display(X: array of const);
var
I: Integer;
begin
for I := 0 to High(X) do with TVarRec(X[I]), Data do
begin
case Tag of
0: ShowMessage('Integer: ' + IntToStr(L));
1: if B then ShowMessage('Boolean: True')
else ShowMessage('Boolean: False');
2: ShowMessage('Char: ' + C);
3: ShowMessage('Float: ' + FloatToStr(E^));
4: ShowMessage('String: ' + S^);
5: ShowMessage('Pointer: ' + PtrToStr(P));
6: ShowMessage('PChar: ' + StrPas(X));
7: ShowMessage('Object: ' + O.ClassName);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
P: array[0..5] of Char;
begin
P := 'Hello'#0;
Display([-12345678, True, 'A', 1.2345, 'ABC', Ptr($1234, $5678),
P,
Form1]);
end;
Here is some more on this subject:
A typical candidate for an Array of Const or open array parameter. An
Array of Const can take a mix of different types, an open array only an
array of items all of the same base class. Inside the function you treat
the array of
const parameter as an open array of TVarRec. Dealing with all the possible
parameter types can be quite complicated, however.
function Max(elem: array of const): TVarRec;
var
i: Word;
b: boolean;
begin
{ Note that open array index range is always zero-based. }
Result := elem[0];
for i := 1 to High(elem) do begin
case Result.VType of
vtInteger:
try
case elem[i].VType of
vtInteger:
b := (elem[i].VInteger > Result.VInteger);
vtChar:
b := (longint(elem[i].VChar) > Result.VInteger);
vtExtended:
b := (elem[i].VExtended^ > Result.VInteger);
vtString:
b := (StrToInt(elem[i].VString^) > Result.VInteger);
vtPChar:
b := (StrToInt(StrPas(elem[i].VPChar)) > Result.VInteger);
else
b := FALSE;
end; {case}
except
b := FALSE;
end;
vtChar:
try
case elem[i].VType of
vtInteger:
b := (char(elem[i].VInteger) > Result.VChar);
vtChar:
b := (elem[i].VChar > Result.VChar);
vtExtended:
b := (elem[i].VExtended^ > longint(Result.VChar));
vtString:
b := (elem[i].VString^ > Result.VChar);
vtPChar:
b := (elem[i].VPChar[0] > Result.VChar);
else
b := FALSE;
end;
except
b := FALSE;
end;
vtExtended:
try
case elem[i].VType of
vtInteger:
b := (elem[i].VInteger > Result.VExtended^);
vtChar:
b := (longint(elem[i].VChar) > Result.VExtended^);
vtExtended:
b := (elem[i].VExtended^ > Result.VExtended^);
vtString:
b := (StrToFloat(elem[i].VString^) > Result.VExtended^);
vtPChar:
b := (StrToFloat(StrPas(elem[i].VPChar)) > Result.VExtended^);
else
b := FALSE;
end; {case}
except
b := FALSE;
end;
vtString:
try
case elem[i].VType of
vtInteger:
b := (elem[i].VInteger > StrToInt(Result.VString^));
vtChar:
b := (elem[i].VChar > Result.VString^);
vtExtended:
b := (elem[i].VExtended^ > StrToFloat(Result.VString^));
vtString:
b := (elem[i].VString^ > Result.VString^);
vtPChar:
b := (StrPas(elem[i].VPChar) > Result.VString^);
else
b := FALSE;
end;
except
b := FALSE;
end;
vtPChar:
try
case elem[i].VType of
vtInteger:
b := (elem[i].VInteger > StrToInt(StrPas(Result.VPChar)));
vtChar:
b := (elem[i].VChar > Result.VPChar[0]);
vtExtended:
b := (elem[i].VExtended^ > StrToFloat(StrPas(Result.VPChar)));
vtString:
b := (elem[i].VString^ > StrPas(Result.VPChar));
vtPChar:
b := (StrComp(elem[i].VPChar, Result.VPChar) > 0);
else
b := FALSE;
end;
except
b := FALSE;
end;
end; {case}
if (b) then Result := elem[i];
end; {for}
end; { Max }