0

指定された行にエラーがある理由を知っている人はいますか?

Type Compatibilityページによると、コンパイラのバグのようです。ワイルドカードは T1、TStringWildcard2 は T2 です。

また、これによると

式の値が T1 の範囲内にあり、次の条件の少なくとも 1 つが満たされる場合、T2 型の式を T1 型の変数に割り当てることができます。T1 が IUnknown または IDispatch インターフェイス型であり、T2 が Variant または Variant またはOleVariant。(バリアントの型コードは、T1 が IUnknown の場合は varEmpty、varUnknown、または varDispatch である必要があり、T1 が IDispatch の場合は varEmpty または varDispatch である必要があります。)

T1 が IUnknown で T2 が OleVariant の場合、T2 型の式を T1 型の変数に代入できます。したがって、2 番目のエラー行もコンパイルする必要があります。

ACollection2 := ACollection1; // 理論的にはコンパイルする必要がありますが、コンパイルしません。LWildcard := TStringWildcard2.Create であるため (LWildcard は Wildcard インターフェイスの変数として宣言されており、TStringWildcard2 は Wildcard インターフェイスを実装しているため、コンパイルされます)。

As such, therefore, ACollection2 (TDictionary<string, Wildcard> ) := ACollection1; (TDictionary<string, TStringWildcard2>) should compile right?

program TestCollections;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, System.Generics.Collections;
type
  Wildcard = interface
  ['{941128E5-D87C-4E3E-98D8-CF45EE6FEC09}']
    procedure Clear;
  end;
  Wildcard<T> = interface(Wildcard)
    function  getMatch: T;
  end;
  TParent = class(TInterfacedObject)
  end;
  TStringWildcard1 = class(TParent, Wildcard<string>)
    function  getMatch: string;
    procedure Clear;
  end;
  TStringWildcard2 = class(TParent, Wildcard, Wildcard<string>)
    function  getMatch: string;
    procedure Clear;
  end;

{ TStringWildcard1 }

procedure TStringWildcard1.Clear;
begin
end;

function TStringWildcard1.getMatch: string;
begin
  Result := 'String match 1';
end;

{ TStringWildcard2 }

procedure TStringWildcard2.Clear;
begin
end;

function TStringWildcard2.getMatch: string;
begin
  Result := 'String match 2';
end;

var
  LWildcard: Wildcard;
  ACollection1: TDictionary<string, TStringWildcard2>;
  ACollection2, ACollection3: TDictionary<string, Wildcard>;
  ACollection4: TDictionary<string, IUnknown>;
begin
  LWildcard := TStringWildCard2.Create; // <-- TStringWildcard2 compatible with Wildcard
// Since TStringWildcard2 is compatible with Wildcard, therefore, 
// ACollection1 should be compatible with ACollection2
  ACollection1 := TDictionary<string, TStringWildcard2>.Create;
  ACollection2 := ACollection1;
  ACollection4 := TDictionary<string, OleVariant>.Create;
end.
4

2 に答える 2