指定された行にエラーがある理由を知っている人はいますか?
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.