2015-08-05 2 views
-1

У меня есть следующее устройство, которое я использовал для некоторых версий Delphi. Но теперь я тестирую X Е8, и я получаю сообщение об ошибке вSystem.Generics.Collections различия в XE8 по сравнению с другими версиями Delphi

function THolydayList.TEnglishNameCollection.ToArray: TArray<string>; 
begin 
    Result := ToArrayImpl(fList.Count); 
end; 

Я думаю, что это имеет отношение к тому, что System.Generics.Collections перезаписывается в X Е8. Но на время времени у меня не было возможности заглянуть в это. Мой вопрос: кто-нибудь заглянул в это и может вести меня в направлении, в зависимости от того, что искать.

Пример моего использование данного устройства может быть следующим, где я обновить таблицу с датами, связанными с работодателем в течение данного года

procedure TsCalendarYearHolyday(aEmployer: string; aYear: integer); 
var 
    STDDato: TStdDato; 
    HolyDay : THolyDay; 
    Query: TUniQuery; 
begin 
    Query := frmUniConn.CreateQuery; 
    STDDato := TStdDato.Create; 
    STDDato.Year := aYear; 
    STDDato.Country := Denmark; 
    STDDato.MarkSunday := False; 
    STDDato.Language := hdNative; 
    STDDato.MakeHoliDays(0); 
    try 
    Query.SQL.Clear; 
    Query.SQL.Add('UPDATE ' + TableTsCalendarYear); 
    Query.SQL.Add(' SET flddayspecial = :flddayspecial'); 
    Query.SQL.Add('  ,flddaydesc = :flddaydesc'); 
    Query.SQL.Add('  ,flddaynormal = :flddaynormal'); 
    Query.SQL.Add(' WHERE (flddate = :flddate)'); 
    Query.SQL.Add(' AND (fldemployer = :fldemployer)'); 
    for HolyDay in STDDato.Liste do 
     begin 
     try 
      Query.ParamByName('flddayspecial').AsBoolean := True; 
      Query.ParamByName('flddaydesc').AsString := Holyday.NativeName; 
      Query.ParamByName('flddaynormal').AsFloat := 0; 
      Query.ParamByName('flddate').AsDate := HolyDay.Date; 
      Query.ParamByName('fldemployer').AsString := aEmployer; 
      Query.Execute; 
     except 
      on E: exception do 
      Logfile.Error('U_TsCalendars.TsCalendarYearHolyday: ' + E.Message); 
     end; 
     end; 
    finally 
    FreeAndNil(STDDato); 
    Query.Free; 
    end; 
end; 

I added a link since this is the whole unit

+2

«Я получаю сообщение об ошибке», какую ошибку? У вас не было времени посмотреть, что вызвало ошибку с вашим кодом, и вы ожидаете, что мы это сделаем? –

+0

Извините, но забыл об ошибке [dcc32 Ошибка] U_Helligdage.pas (873): E2003 Необъявленный идентификатор: 'ToArrayImpl' – OZ8HP

+0

Сторона примечания: оберните изменение текста SQL в 'SQL.BeginUpdate' и' SQL.EndUpdate'. –

ответ

3

Это немного расстраивает, что вы говорите «Я получаю сообщение об ошибке», не указывая, что это за ошибка. Ошибка выполнения? Ошибка времени компиляции? Пожалуйста, обратите внимание на ошибки. По моему опыту, когда люди не говорят, что такое ошибка, это часто происходит потому, что они не читали сообщение об ошибке близко и пытались понять это. Это обычно ошибка. Поэтому мой самый большой совет - обратить внимание на такие детали и, надеюсь, поможет вам решить такие проблемы для себя в будущем.


Однако, так как это достаточно ясно, что вызов ToArrayImpl не будет компилироваться, потому что ToArrayImpl является частным членом, мы можем решить это.

Очевидно, что вы не можете позвонить ToArrayImpl, потому что он является частным. И единственный способ, которым мы можем разобраться в том, что вам нужно, - это прочитать код на вашем сайте. Опять же, не идеально. Этот код будет компилироваться и вести себя так, как вы планируете.

function THolydayList.TEnglishNameCollection.ToArray: TArray<string>; 
var 
    i: Integer; 
begin 
    SetLength(Result, fList.Count); 
    for i := 0 to fList.Count-1 do 
    Result[i] := fList[i].EnglishName; 
end; 

Независимо от того, является ли это наилучшим решением вашей проблемы, я не готов говорить.


Теперь можно задаться вопросом, как ваш код когда-либо работал. Это было связано с ошибками компилятора в более старых версиях. Метод ToArrayImpl всегда был закрыт. Старые версии компилятора не смогли правильно обеспечить эту видимость и позволили вашему классу позвонить ToArrayImpl, когда он не был предназначен.

Этот код:

uses 
    Generics.Collections; 

type 
    TMyEnumerable<TObject> = class(TEnumerable<TObject>) 
    procedure Foo; 
    end; 

procedure TMyEnumerable<TObject>.Foo; 
begin 
    ToArrayImpl(0); 
end; 

компилирует в XE7, но не X Е8. Очевидно, что старые компиляторы были сломаны.

+0

Ссылка на сайт была выбрана для того, чтобы включить как можно больше кода, поэтому я не забыл код, необходимый для просмотра проблемы. – OZ8HP

+1

Да, была ошибка в generics, которая позволяла доступ к закрытым членам из класса предков, которые были исправлены в XE8 (я не могу найти для него какую-либо запись QC или QP). –

+2

@ OZ8HP Обратите внимание, что я сократил его до 10 строк. На мой взгляд, это важный навык для изучения. Изоляция проблемы - первая часть решения проблем. –

Смежные вопросы