I have a record type defined like:
type
TRecordType = record
Field1: string;
Field2: Variant;
end;
And a function declaration using it:
function Function1(const Records: TArray<TRecordType>): TAnyOtherClass;
So far so good, but if the function is called like:
Function1([BuildRecord('string', value), BuildRecord('OtherString', otherValue)])
The compiler returns an error:
[DCC Error] AnyUnit.pas(142): E2001 Ordinal type required
I have read some place a long time ago that Delphi's compiler handles generics in a kind of preprocessor with string replacements done before really compiling the code, so I was expecting Function1
to become something like:
function Function1(const Records: array of TRecordType): TAnyOtherClass;
Because TArray
is defined TArray<T> = array of T;
.
I think it is not happening, because when I changed the function declaration to:
function Function1(const Records: array of TRecordType): TAnyOtherClass;
The code is compiled without errors or warnings.
There is an answer on [this question] 1 that links to an article explaining the difference, but the link there is broken.
So my question is, what means TArray<T>
if not array of T
?
Function1([BuildRecord('string', value), BuildRecord('OtherString', otherValue)])
The [...]
syntax in your argument is what is known as an open array constructor. This documentation states, with my emphasis:
Open array constructors allow you to construct arrays directly within function and procedure calls. They can be passed only as open array parameters or variant open array parameters.
Your function accepts a (generic) dynamic array type, which is different from an open array. Your function is declared as
function Function1(const Records: TArray<TRecordType>): TAnyOtherClass;
The parameter is a (generic) dynamic array type. An open array parameter would look like this:
function Function1(const Records: array of TRecordType): TAnyOtherClass;
I know this looks very like the declaration of a dynamic array, but it is not. In Delphi, array of
has two distinct meanings:
array of
is used to declare an open array parameter.array of
defines a dynamic array type.This overloading of the language syntax is a common cause for confusion.
So, because of all this, the compiler rejects your code, because you are attempting to use an open array constructor with a parameter that is not an open array.
My answer here goes into this issue in more detail: https://stackoverflow.com/a/14383278/505088
I have read some place a long time ago that Delphi's compiler handles generics in a kind of preprocessor and some kind of string replace in code.
I think you are mis-remembering. What you are describing is more akin to C++ templates. Delphi generics are not handled by a preprocessor, not least because Delphi does not have a preprocessor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With