Jump to content
Zoë Peterson

"Incompatible parameter lists" when using Types.T*DynArray?

Recommended Posts

I have some visual components that have event handlers that are declared like so:

TSsInitEvent = procedure(Sender: TObject; var AStrs: TStringDynArray) of object;

In the units that are using them, they're declared like:

procedure CommandControlInit(Sender: TObject; var AStrs: TStringDynArray);

Ctrl+Clicking shows that TStringDynArray is a direct reference to System.Types.TStringDynArray in both cases.  In the older releases, TStringDynArray was "array of string", but it's apparently now been changed to "TStringDynArray = TArray<string>".

 

That worked just fine in older Delphi releases, but in 11.3 whenever I save the form I get the error "The CommandControlInit method referenced by CommandControl.OnInit has an incompatible parameter list.  Remove the reference?"

 

If I try to create a new event for the relevant property, it's created like so:

procedure CommandControlInit(Sender: TObject; var AStrs: TArray<System.string>);

Aside from just being a more obnoxious declaration, that doesn't work for projects that also need to compile in older Delphi releases.

 

Has anyone else run into this?  Any good workarounds?  Any open bug reports about it I can vote for?

Share this post


Link to post

This doesn't seem to hang together. Could you provide a complete program to demonstrate the issue. 

 

I get that if you need to support pre generics versions then TArray<string> is out but if you don't need to support those ancient versions then this for is much preferable. 

Share this post


Link to post

Sure, here's a trivial example.  Compile/install the SsExample.bpl, which adds a new minimal TSsControl.  SsProj.dproj already has a form with the relevant control.  If you make any change at all to it, you'll get the error.  If you delete the existing CtrlInit and add a new one, it'll switch to the generic declaration.

 

This isn't restricted to something as simple  as TArray<string> though.  If the argument is a much more complicated generics declaration (e,g. TDictionary<string, TDictionary<Integer, Integer>>), that gets exploded out too.  Why would that be preferable to using a named alias?

DynArrayFailure.zip

Share this post


Link to post

I suspect you only could change the event declaration to generics or define your own alias. Type aliases have pretty much quirks (for ex., even if T1 and T2 are declared identically, they're not compatible).

Share this post


Link to post

Using TArray<T> is better because it doesn't have type compatibility issues like this. It makes it easy for different libraries to interop. Because the different libraries don't need to know about each other and declare types in a shared unit. 

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×