Я встретил странное ограничение компилятора Delphi (Токио) при попытке передать экземпляр универсального списка в универсальный метод, тогда как передача универсального массива в компилятор метода (1) принимает, и все работает как ожидалось.
(1) class procedure DoSomethingWithDynamicArray<T: class>(AArray: array of T);
(2) class procedure DoSomethingWithGenericArray<T: class>(AArray: TArray<T>);
(3) class procedure DoSomethingWithGenericList<T: class>(AList: TList<T>);
Но при передаче того же массива методу с сигнатурой (2) Delphi выдает ошибку:
[dcc32 Error] Project8.dpr(49): E2010 Incompatible types: 'System.TArray<....TSomeClass.DoSomethingWithGenericArray.T>' and 'System.TArray<....TBaseClass>'
, даже если TArray<T>
объявлено как array of <T>
.
Та же ошибка возникает при передаче общего списка методу (3).
В чем причина такого ограничения?Но в первую очередь , как реализовать такие вещи в Delphi?(например, в C # нет таких ограничений).
Я прочитал некоторые объяснения относительно возможного наследования <T>
, но я не принимаю такой аргумент, потому что та же проблема может возникнуть с массивами, и компилятор принимает ее:
SomeArray: TArray<TBaseClass>;
SomeArray := [TBaseClass.Create, TDescendantClass.Create,
TGrandDescendantClass.Create];
TSomeClass.DoSomethingWithDynamicArray(SomeArray);
ОБНОВЛЕНИЕ: пример
program Project8;
uses
System.SysUtils, System.Generics.Collections;
type
TBaseClass = class
end;
TDescendantClass = class(TBaseClass)
end;
TGrandDescendantClass = class(TDescendantClass)
end;
TSomeClass = class
class procedure DoSomethingWithDynamicArray<T: class>(AArray: array of T);
class procedure DoSomethingWithGenericArray<T: class>(AArray: TArray<T>);
class procedure DoSomethingWithGenericList<T: class>(AList: TList<T>);
end;
var
SomeArray: TArray<TBaseClass>;
SomeList: TList<TBaseClass>;
class procedure TSomeClass.DoSomethingWithDynamicArray<T>(AArray: array of T);
begin
end;
class procedure TSomeClass.DoSomethingWithGenericArray<T>(AArray: TArray<T>);
begin
end;
class procedure TSomeClass.DoSomethingWithGenericList<T>(AList: TList<T>);
begin
end;
begin
try
SomeArray := [TBaseClass.Create, TDescendantClass.Create,
TGrandDescendantClass.Create];
TSomeClass.DoSomethingWithDynamicArray(SomeArray);
TSomeClass.DoSomethingWithGenericArray(SomeArray); //E2010: Incompatible type
SomeList := TList<TBaseClass>.Create;
SomeList.AddRange([TBaseClass.Create, TDescendantClass.Create,
TGrandDescendantClass.Create]);
TSomeClass.DoSomethingWithGenericList(SomeList); //E2010: Incompatible type
except on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.