Я борюсь с универсальным классом Spring4D (1.2.2) TMultiMap. Я хочу вызвать перегруженный конструктор, и компилятор пожалуется:

"E2250 There is no overloaded version of 'Create' that can be called with these arguments"

Аргумент - это правильный тип в соответствии с исходным кодом Spring4D.

Я разработал небольшую программу, воспроизводящую ошибку:

program Spring4DMultiMapTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
    System.SysUtils,
    Generics.Collections,
    Spring.Tests.Interception.Types,
    Spring.Collections.MultiMaps,
    Spring.Collections;

type
    TMyKey = TPair<Double, Integer>;

    TMyKeyEqualityComparer = class(TInterfacedObject, IEqualityComparer<TMyKey>)
        function Equals(const Left, Right: TMyKey): Boolean; reintroduce;
        function GetHashCode(const Value: TMyKey): Integer; reintroduce;
    end;

function TMyKeyEqualityComparer.Equals(const Left, Right: TMyKey): Boolean;
begin
    if Left.Key < (Right.Key - 1E-9) then
        Result := TRUE
    else if Left.Key > (Right.Key + 1E-9) then
        Result := FALSE
    else if Left.Value < Right.Value then
        Result := TRUE
    else
        Result := FALSE;
end;

function TMyKeyEqualityComparer.GetHashCode(const Value: TMyKey): Integer;
begin
    Result := Value.Value + Round(Value.Key * 1E6);
end;

var
    Events      : IMultiMap<TMyKey, Integer>;
    KeyComparer : IEqualityComparer<TMyKey>;
begin
    KeyComparer := TMyKeyEqualityComparer.Create;
    // Next line triggers error: "E2250 There is no overloaded version of 'Create' that can be called with these arguments"
    Events := TMultiMap<TMyKey, Integer>.Create(KeyComparer);
end.

В исходном коде Spring4D я нахожу следующее объявление:

TMultiMap<TKey, TValue> = class(TMultiMapBase<TKey, TValue>)

А также объявлен TMultiMap acestor:

  TMultiMapBase<TKey, TValue> = class abstract(TMapBase<TKey, TValue>,
    IMultiMap<TKey, TValue>, IReadOnlyMultiMap<TKey, TValue>)

И имеет этот конструктор:

constructor Create(const keyComparer: IEqualityComparer<TKey>); overload;

Это конструктор, который я хочу вызвать. Насколько я понимаю, мой аргумент KeyComparer имеет правильный тип. Но компилятор явно не согласен :-(

Как исправить этот код?

1
fpiette 9 Фев 2021 в 20:17

1 ответ

Лучший ответ

Вы используете разные типы IEqualityComparer<T>.

IEqualityComparer<T> в вашем примере происходит от Spring.Tests.Interception.Types.pas. Тот, который используется в конструкторе TMultiMap<TKey, TValue>.Create, определен в System.Generics.Defaults.pas.

Если вы измените свою часть uses на

uses
    System.SysUtils,
    Generics.Collections,
    // Spring.Tests.Interception.Types,
    Generics.Defaults,
    Spring.Collections.MultiMaps,
    Spring.Collections;

Ваш пример будет компилироваться.

Протестировано с Delphi 10.3 U3 и Spring4D 1.2.2

3
G Wimpassinger 9 Фев 2021 в 21:49