Использование собственного класса в качестве ограничения параметра типа в объявлении класса
У меня есть следующее объявление класса в Delphi XE8:
TestClass = class;
TestClass = class
function test<T: TestClass>(supplier: TFunc<T>): T; // Compiler error
end;
Который выдает следующую ошибку компилятора:
E2086 Type 'TestClass' is not yet completely defined
Когда я добавляю в класс другой класс и использую его как ограничение, он работает нормально:
AnotherTestClass = class
end;
TestClass = class;
TestClass = class
function test<T: AnotherTestClass>(supplier: TFunc<T>): T; // No Error
end;
Я подозреваю, что проблема заключается в том, что объявление типа forward недостаточно сообщает Delphi о TestClass
типа еще. Это, возможно, более очевидно, поскольку следующая попытка обойти проблему выдает ту же ошибку компилятора в другой строке:
TestClass = class;
AnotherTestClass = class (TestClass) // Compiler Error
end;
TestClass = class
function test<T: AnotherTestClass>(supplier: TFunc<T>): T;
end;
Я делаю что-то не так, и если нет, есть ли способ обойти эту проблему?
1 ответ
Вы не делаете ничего плохого. То, что вы пытаетесь сделать, должно быть возможным, но компилятор, на мой взгляд, неисправен. Там нет никакого жизнеспособного способа обойти это без полного изменения дизайна. Один из способов обойти эту проблему заключается в применении ограничения во время выполнения. Однако, на мой взгляд, это полностью изменило бы дизайн.
Обратите внимание, что в.net то, что вы пытаетесь сделать, вполне возможно:
class MyClass
{
private static T test<T>(Func<T> arg) where T : MyClass
{
return null;
}
}
Функция обобщений Delphi была основана на обобщениях.net, и я скорее подозреваю, что проблема, с которой вы сталкиваетесь, сводится к недосмотру со стороны разработчиков Delphi.
Вы должны отправить отчет об ошибке / запрос функции.
Обновление 1
LU RD предлагает лучший обходной путь. Используйте помощник класса:
type
TestClass = class
end;
TestClassHelper = class helper for TestClass
function test<T: TestClass>(supplier: TFunc<T>): T;
end;
Это позволит вам проверить ограничение во время компиляции. Тем не менее, это заставляет вас определять метод вне функции, которая является неопрятной, и останавливает использование помощника класса для любых других целей. Таким образом, вы все равно должны отправить отчет об ошибке / запрос функции на мой взгляд.
Обновление 2