我想定义一个由不同类型组成的数组类型,例如String,Integer,Boolean,Double等,但没有对象,结构或任何这种性质.然后我想将此类型用作函数参数,例如……
type
TMyArray = array of ...?...;
function GetSomething(const Input: TMyArray): String;
var
X: Integer;
begin
for X:= 0 to Length(Input) - 1 do begin
//Identify type and handle accordingly...
//Serialize data for the result...
end;
end;
并像…一样使用它
Variable:= GetSomething(['some string',123,'something else',12.3,false]);
那么,在迭代这样一个数组时,如何识别每个元素的类型?
我很确定这是可能的,但甚至不知道要搜索什么术语.我该怎么做呢?
我是否必须将其定义为Variants数组?或者有没有办法确定数组接受哪些类型?
编辑
不要改变任何问题,但在RRUZ的答案之后,我发现了an intriguing article关于性能的不同方式……
解决方法
如果你的Delphi版本支持RTTI,你可以使用
TValue的数组和Kind属性.
{$APPTYPE CONSOLE}
uses
System.TypInfo,System.Rtti,System.SysUtils;
function GetSomething(const Input: array of TValue): String;
var
X: Integer;
LValue : TValue;
begin
for LValue in Input do begin
case LValue.Kind of
tkUnkNown: Writeln('UnkNown');
tkInteger: Writeln(Format('The Kind of the element is Integer and the value is %d',[LValue.AsInteger]));
tkChar: Writeln('Char');
tkEnumeration: if LValue.TypeInfo=TypeInfo(Boolean) then Writeln(Format('The Kind of the element is Boolean and the value is %s',[BoolToStr(LValue.AsBoolean,True)]));
tkFloat: Writeln(Format('The Kind of the element is Float and the value is %n',[LValue.AsExtended]));
tkString: Writeln('String');
tkSet: Writeln('Set');
tkClass: Writeln('Class');
tkMethod:Writeln('method');
tkWChar: Writeln('WChar');
tkLString: Writeln('String');
tkWString: Writeln('String');
tkVariant: Writeln('Variant');
tkArray: Writeln('Array');
tkRecord: Writeln('Record');
tkInterface: Writeln('Interface');
tkInt64: Writeln('Int64');
tkDynArray: Writeln('DynArray');
tkUString: Writeln(Format('The Kind of the element is String and the value is %s',[LValue.Asstring]));
tkClassRef: Writeln('Class Ref');
tkPointer: Writeln('Pointer');
tkProcedure: Writeln('procedure');
end;
end;
end;
begin
try
GetSomething(['some string',false]);
except
on E: Exception do
Writeln(E.ClassName,': ',E.Message);
end;
Readln;
end.
另一种选择是使用const数组
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure GetSomething(const Input: array of const);
var
LIndex: Integer;
begin
for LIndex := Low(Input) to High(Input) do
begin
case Input[LIndex].VType of
vtWideString: Writeln('WideString = ''',WideString(Input[LIndex].VWideChar),'''');
vtInt64: Writeln('Int64 = ',Input[LIndex].VInt64^);
vtCurrency: Writeln('Currency = ',CurrToStr(Input[LIndex].VCurrency^));
vtInteger: Writeln('Integer = ',Input[LIndex].VInteger);
vtBoolean: Writeln('Boolean = ',BoolToStr(Input[LIndex].VBoolean,True));
vtChar: Writeln('Char = ''',Input[LIndex].VChar,'''');
vtExtended: Writeln('Extended = ',FloatToStr(Input[LIndex].VExtended^));
vtString: Writeln('ShortString = ''',Input[LIndex].VString^,'''');
vtPChar: Writeln('PChar = ''',Input[LIndex].VPChar,'''');
vtAnsiString: Writeln('AnsiString = ''',Ansistring(Input[LIndex].VAnsiString),'''');
vtWideChar: Writeln('WideChar = ''',Input[LIndex].VWideChar,'''');
vtPWideChar: Writeln('PWideChar = ''',Input[LIndex].VPWideChar,'''');
vtUnicodeString : Writeln('UnicodeString = ''',string(Input[LIndex].VUnicodeString),'''');
else
Writeln('Unsupported');
end;
end;
end;
begin
try
GetSomething(['some string',E.Message);
end;
Readln;
end.