For reasons I need to have something like this:
DT: array[0..3] of types = (string, integer, double, boolean);
Is this even possible?
Even if it would compile, the resulting DT[]
array won't be usable for any profit.
You could only use something like
var v: DT[0]; // this will be a string variable
but it is clearly pointless, since you have in particular the ability to define custom types:
type
TMyString = type string;
...
var
v: TMyString;
So replace TMyString
by DT[0]
and you get what you expect.
If you expect to use DT[]
e.g. with a loop, e.g. use DT[i]
, I don't see any possible use of this syntax.
What I usually do on the other hand, is either:
variant
variable to store any kind of value - I guess this is what you wanted to reinvent;First, variant
values are pretty powerful:
var v: variant;
begin
v := 1; // now v holds an integer
ShowMessage(v); // will be converted to string before display
if VarIsStr(v) then // false
ShowMessage('string')
else if VarIsNumeric(v) then // true
ShowMessage('number');
v := 'toto'; // now v holds a string
ShowMessage(v);
if VarIsStr(v) then // true
ShowMessage('string')
else if VarIsNumeric(v) then // false
ShowMessage('number');
v := true; // now v holds a boolean
if VarIsStr(v) then // false
ShowMessage('string')
else if VarIsNumeric(v) then // false
ShowMessage('number')
else if VarIsBool(v) then // true
ShowMessage('boolean');
...
And for metaclasses:
type
TMyClassParent = class
...
end;
TMyClass1 = class(TMyClassParent)
...
end;
TMyClass2 = class(TMyClassParent)
...
end;
TMyClass3 = class(TMyClass1)
...
end;
// define the meta-class type
TMyClassParentClass = class of TMyClassParent;
// define an enumeration
TMyClasses = (myclass1, myclass2, myclass3);
const
MYCLASS_NAME: array[TMyClasses] of string = (
'one', 'two', 'three');
MYCLASS_CLASS: array[TMyClasses] of TMyClassParentClass = (
TMyClass1, TMyClass2, TMyClass3);
var
c: TMyClassParent;
cc: TMyClasses;
begin
for cc := low(cc) to high(cc) do
begin
writeln('Using ', MYCLASS_CLASS[cc].ClassName, ' for class ', MYCLASS_NAME[cc]);
c := MYCLASS_CLASS[cc].Create;
try
// use Liskov's friendly c instance
finally
c.Free;
end;
end;
end.
And if you follow properly Liskov's substitution principle, you may use c: TMyClassParent
in an abstract manner, since the children wouldn't affect the expectations of the parent class behavior.