System.Generics.Collections XE8 与其他 Delphi 版本相比的差异
System.Generics.Collections differences in XE8 compared to other Delphi versions
我有以下用于某些 Delphi 版本的单元。但是现在我正在测试 XE8 并且在
中出现错误
function THolydayList.TEnglishNameCollection.ToArray: TArray<string>;
begin
Result := ToArrayImpl(fList.Count);
end;
我认为这与 System.Generics.Collections 在 XE8 中被重写有关。但是时间紧迫,我还没有机会去研究那个。
我的问题是:有没有人调查过这个并且可以指导我寻找什么的方向。
我使用这个单位的一个例子如下,我用给定年份
与雇主相关的日期更新 table
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 get an error" 而没有说明错误是什么,这有点令人沮丧。 运行时间错误?编译时错误?请准确指出错误。根据我的经验,当人们不说出错误是什么时,通常是因为他们没有仔细阅读错误消息并试图理解它。这通常是一个错误。所以我给你最大的建议就是多注意这些细节,希望这能帮助你将来自己解决这些问题。
但是,由于 ToArrayImpl
是私有成员,所以很明显调用 ToArrayImpl
将无法编译,我们可以解决这个问题。
显然你不能调用 ToArrayImpl
因为它是私有的。我们可以计算出您需要的唯一方法是阅读您场外的代码 link。再次,不理想。此代码将按您的预期进行编译和运行。
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
方法一直是私有的。旧版本的编译器无法正确执行该可见性,并允许您的 class 在本不该调用的情况下调用 ToArrayImpl
。
此代码:
uses
Generics.Collections;
type
TMyEnumerable<TObject> = class(TEnumerable<TObject>)
procedure Foo;
end;
procedure TMyEnumerable<TObject>.Foo;
begin
ToArrayImpl(0);
end;
在 XE7 中编译,但在 XE8 中不编译。显然旧的编译器坏了。
我有以下用于某些 Delphi 版本的单元。但是现在我正在测试 XE8 并且在
中出现错误function THolydayList.TEnglishNameCollection.ToArray: TArray<string>;
begin
Result := ToArrayImpl(fList.Count);
end;
我认为这与 System.Generics.Collections 在 XE8 中被重写有关。但是时间紧迫,我还没有机会去研究那个。 我的问题是:有没有人调查过这个并且可以指导我寻找什么的方向。
我使用这个单位的一个例子如下,我用给定年份
与雇主相关的日期更新 tableprocedure 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 get an error" 而没有说明错误是什么,这有点令人沮丧。 运行时间错误?编译时错误?请准确指出错误。根据我的经验,当人们不说出错误是什么时,通常是因为他们没有仔细阅读错误消息并试图理解它。这通常是一个错误。所以我给你最大的建议就是多注意这些细节,希望这能帮助你将来自己解决这些问题。
但是,由于 ToArrayImpl
是私有成员,所以很明显调用 ToArrayImpl
将无法编译,我们可以解决这个问题。
显然你不能调用 ToArrayImpl
因为它是私有的。我们可以计算出您需要的唯一方法是阅读您场外的代码 link。再次,不理想。此代码将按您的预期进行编译和运行。
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
方法一直是私有的。旧版本的编译器无法正确执行该可见性,并允许您的 class 在本不该调用的情况下调用 ToArrayImpl
。
此代码:
uses
Generics.Collections;
type
TMyEnumerable<TObject> = class(TEnumerable<TObject>)
procedure Foo;
end;
procedure TMyEnumerable<TObject>.Foo;
begin
ToArrayImpl(0);
end;
在 XE7 中编译,但在 XE8 中不编译。显然旧的编译器坏了。