D12 and CreateDicitonary

140 views
Skip to first unread message

mi...@margerum.com

unread,
Nov 25, 2023, 9:20:41 AM11/25/23
to Spring4D
Hello, this code used to compile in d11 and spring 1.x

I've upgraded to d12 and spring 2.x

The problem is with the doOwnsValues which comes is a set that comes from spring.pas

[dcc32 Error] DBContext.pas(797): E2250 There is no overloaded version of 'TCollections.CreateDictionary<System.string,Customer.TCustomer>' that can be called with these arguments

------------------
code
-----------------

constructor TDBContext.Create;
begin
    inherited;
    FCustomerDictionary := TCollections.CreateDictionary<string, TCustomer>
      ([doOwnsValues]);

Stefan Glienke

unread,
Nov 25, 2023, 1:07:23 PM11/25/23
to Spring4D
Make sure that Generics.Collections is not in uses *after* Spring.Collections (or Spring)

obones

unread,
Nov 27, 2023, 9:48:10 AM11/27/23
to Spring4D
I'm facing the same situation here, and this is turning into quite a pain as we have the following ordering of uses rule:
Delphi Units
Third party units
Project units

This clashes with your recommandation, and even if I was to follow it, I would need to go into dozens of units to change it.

There must be a very good reason behind the fact that you chose to create such a name collision, but it's quite impractical for us.

Stefan Glienke

unread,
Nov 27, 2023, 9:50:49 AM11/27/23
to Spring4D
The reason is that there is literally no necessity to have Generics.Collections in the uses at all.
If you don't like that you are free to redirect TDictionaryOwnerships back to the RTL.

Stefan Glienke

unread,
Nov 27, 2023, 9:54:20 AM11/27/23
to Spring4D
Also, the unit order you mentioned is exactly how I recommended it - notice I said make sure that RTL unit is not after Spring or Spring.Collections.
Of course if you follow that order you will have to quality the one from the RTL but as I said, there is no necessity to use anything dictionary or even collection related from the RTL at all.

obones

unread,
Nov 27, 2023, 10:07:10 AM11/27/23
to Spring4D

Yes, I understand the logic behind not depending on such a bloated unit.
But it would have made our life easier if the individual names of the set were not to use the same name as the ones from System.Generics.Collections as this is where we get the most clashes.
Something like this for instance:

  /// <summary>
  ///   Controls the ownership of objects stored in any associative collection.
  /// </summary>
  TDictionaryOwnerships = set of (
    /// <summary>
    ///   Objects stored as key are being destroyed when removed
    /// </summary>
    doSpringOwnsKeys,

    /// <summary>
    ///   Objects stored as value are being destroyed when removed
    /// </summary>
    doSpringOwnsValues
  );


Sure, this requires changes in the 5 Spring units where they are used but I feel that it interferes less with Spring user code.

My 2 cents

obones

unread,
Nov 27, 2023, 10:07:10 AM11/27/23
to Spring4D
I see the exact opposite, my uses list is the following:

uses
  Classes, SyncObjs, SysUtils, System.Generics.Collections, Math, Windows, StrUtils, Spring, myProjectUnit;

And yet, I get an error on this line of code:

  MyDict := TObjectDictionary<TSomeKey, TSomeValue>.Create([doOwnsValues]);

Renaming the individual items in Spring.TDictionaryOwnership fixed the issue. Exchanging the units in the uses clause works too, but I want to avoid this.

Stefan Glienke

unread,
Nov 27, 2023, 10:09:19 AM11/27/23
to Spring4D
Then your use case is not the same as Mikes - you are obviously creating the RTL dictionary where it needs the RTL TOwnerships.
Simply remove the declaration from Spring so it only resides in Spring.Collections - I have to actually review why I moved it to Spring.pas that could have been a mistake because now it creeps into the scope even if you don't do anything spring.collections.

Reply all
Reply to author
Forward
0 new messages