Решение проблемы с ошибкой E2430 в Delphi для новичков из C
Если вы только начинаете изучать Delphi, но имеете опыт работы с C#, то вам, скорее всего, будет знакомо желание использовать те же подходы и техники, к которым вы привыкли в C#. Однако, иногда это может приводить к ошибкам, которые могут быть не так очевидны для новичков. Одна из таких ошибок - E2430, возникающая при попытке использовать цикл for..in для перебора коллекции.
Описание проблемы
Рассмотрим следующий код, в котором пытаются перебрать коллекцию TJobActivityDetailCollection с помощью цикла for..in:
type
TJobActivityDetailCollection = class(TObjectList<TJobActivityDetail>)
class function ForYear(year: integer): TJobActivityDetailCollection;
end;
class function TJobActivityDetailCollection.ForYear(year: integer): TJobActivityDetailCollection;
var
returnCollection: TJobActivityDetailCollection;
yearStart, yearEnd: TDateTime;
jobActivity: TJobActivityDetail;
begin
yearStart := EncodeDateTime(year, 7, 1, 0, 0, 0, 0);
yearEnd := EncodeDateTime(year + 1, 6, 30, 23, 59, 59, 0);
returnCollection := TJobActivityDetailCollection.Create();
for jobActivity in self do
begin
if (jobActivity.Date > yearStart) and (jobActivity.Date > yearEnd) then
begin
returnCollection.Add(jobActivity);
end;
end;
Result := returnCollection;
end;
При попытке компиляции этого кода вы получите ошибку:
E2430: for-in statement cannot operate on collection type 'Class reference'
Причина ошибки
Причина ошибки заключается в том, что в Delphi классовые методы (методы, объявленные с помощью class) не имеют доступа к self (аналогу this в C#). В данном случае, self ссылается на тип класса TJobActivityDetailCollection, а не на экземпляр этого класса. Цикл for..in пытается перебирать экземпляр класса, а не сам тип, что и вызывает ошибку.
Решение проблемы
Чтобы решить проблему, достаточно удалить спецификатор class из объявления метода ForYear. Таким образом, метод станет экземплярным (инстанс-методом), и у него появится доступ к self:
type
TJobActivityDetailCollection = class(TObjectList<TJobActivityDetail>)
function ForYear(year: integer): TJobActivityDetailCollection;
end;
function TJobActivityDetailCollection.ForYear(year: integer): TJobActivityDetailCollection;
var
returnCollection: TJobActivityDetailCollection;
yearStart, yearEnd: TDateTime;
jobActivity: TJobActivityDetail;
begin
yearStart := EncodeDateTime(year, 7, 1, 0, 0, 0, 0);
yearEnd := EncodeDateTime(year + 1, 6, 30, 23, 59, 59, 0);
returnCollection := TJobActivityDetailCollection.Create();
for jobActivity in self do
begin
if (jobActivity.Date > yearStart) and (jobActivity.Date > yearEnd) then
begin
returnCollection.Add(jobActivity);
end;
end;
Result := returnCollection;
end;
Теперь код должен компилироваться без ошибок.
Заключение
При работе с Delphi важно понимать разницу между классовыми и экземплярными методами. Классовые методы не имеют доступа к self, в отличие от экземплярных. Если вам нужно перебрать коллекцию в методе, убедитесь, что метод объявлен как экземплярный, а не классовый.
Контекст: Описание ошибки E2430 в Delphi и способы её решения для новичков, переходящих с C#.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.