我有一些我以前从未见过的东西。调试时未在“局部变量”窗口中显示的局部变量。我正在附加图片。
如您所见,我在代码中使用变量,并在调试时禁用优化。但我也使用泛型和匿名方法,我不是专家。 有问题的过程的代码是这样的(该过程的作用是按顺序排列第一个数组ArrayNomes,ArrayValores按第一个数组中字符串的长度排序):
procedure OrdenarArrays(var ArrayNomes, ArrayValores: array of string; var ArrayIndices: array of Integer);
var
Comparer: IComparer<Integer>;
I: Integer;
tmpNomesCampos, tmpValoresCampos: array of String;
begin
SetLength(tmpNomesCampos, cdsCadastro.FieldCount);
SetLength(tmpValoresCampos, cdsCadastro.FieldCount);
//Carregar os NomesCampos para serem usados na comparação
for I := 0 to High(arrayIndices) do
begin
tmpNomesCampos[I] := ArrayNomes[I];
end;
{ Cria novo delegatedcomparer. Ele permite o uso de um callback para comparar os arrays}
Comparer := TDelegatedComparer<Integer>.Create(
{ TComparison<Integer> }
function(const Left, Right: Integer): Integer
begin
{colocar em ordem decrescente de acordo com o tamanho do nome do campo}
// Result := Left - Right;
Result := -(Length(tmpNomesCampos[Left]) - Length(tmpNomesCampos[Right]));
end);
{ Ordena o Array base }
TArray.Sort<Integer>(arrayIndices, Comparer);
//Reordenar os NomesCampos de acordo com o array IndicesCampos
for I := 0 to High(arrayIndices) do
begin
tmpNomesCampos[I] := ArrayNomes[arrayIndices[I]];
tmpValoresCampos[I] := ArrayValores[arrayIndices[I]];
end;
//Salvar nos arrays definitivos;
for I := 0 to High(arrayIndices) do
begin
ArrayNomes[I] := tmpNomesCampos[I];
ArrayValores[I] := tmpValoresCampos[I];
end;
end;
此变量是否显示错误?这是一个已知的bug吗?或者它是否是使用我不知道的泛型和匿名方法的功能?
系统:Windows 7 64位/ Delphi XE(最新更新)
更新:将代码更改为下面的简化控制台版本。这可能有助于任何想要在他的Delphi版本中测试的人。 注意:它不会填充原始数组,因为没有必要显示问题;
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Generics.Collections, Generics.Defaults;
procedure OrdenarArrays(var ArrayNomes, ArrayValores: array of string; var ArrayIndices: array of Integer);
var
Comparer: IComparer<Integer>;
I: Integer;
tmpNomesCampos, tmpValoresCampos: array of String;
begin
SetLength(tmpNomesCampos, Length(arrayIndices));
SetLength(tmpValoresCampos, Length(arrayIndices));
//Carregar os NomesCampos para serem usados na comparação
for I := 0 to High(arrayIndices) do
begin
tmpNomesCampos[I] := ArrayNomes[I];
end;
{ Cria novo delegatedcomparer. Ele permite o uso de um callback para comparar os arrays}
Comparer := TDelegatedComparer<Integer>.Create(
{ TComparison<Integer> }
function(const Left, Right: Integer): Integer
begin
{colocar em ordem decrescente de acordo com o tamanho do nome do campo}
// Result := Left - Right;
Result := -(Length(tmpNomesCampos[Left]) - Length(tmpNomesCampos[Right]));
end);
{ Ordena o Array base }
TArray.Sort<Integer>(arrayIndices, Comparer);
//Reordenar os NomesCampos de acordo com o array IndicesCampos
for I := 0 to High(arrayIndices) do
begin
tmpNomesCampos[I] := ArrayNomes[arrayIndices[I]];
tmpValoresCampos[I] := ArrayValores[arrayIndices[I]];
end;
//Salvar nos arrays definitivos;
for I := 0 to High(arrayIndices) do
begin
ArrayNomes[I] := tmpNomesCampos[I];
ArrayValores[I] := tmpValoresCampos[I];
end;
end;
var
NomesCampos, ValoresCampos: array of String;
IndicesCampos: array of Integer;
I: Integer;
begin
try
SetLength(NomesCampos, 42);
SetLength(ValoresCampos, 42);
SetLength(IndicesCampos, 42);
// for I := 0 to 41 do
OrdenarArrays(NomesCampos, ValoresCampos, IndicesCampos);
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
答案 0 :(得分:5)
这是XE5中仍然存在的调试器/ IDE错误。正如您所怀疑的,问题在于使用匿名方法。关键是是否捕获变量。捕获变量时,该变量不会显示在“局部”窗口中。这是我能编制的最短的SSCCE:
{$APPTYPE CONSOLE}
uses
System.SysUtils;
procedure Foo1;
var
func: TFunc<Integer>;
val: Integer;
begin
val := 666;
func :=
function: Integer
begin
Result := val;
end;
end;
procedure Foo2;
var
func: TFunc<Integer>;
val: Integer;
begin
val := 666;
func :=
function: Integer
begin
Result := 666;
end;
end;
begin
Foo1;
Foo2;
Readln;
end.
在调试器中,Foo1.val
未显示在“本地”窗口中。但Foo2.val
确实如此。
答案 1 :(得分:0)
不是问题的答案,而是关于如何以更简单的方式编写例程的建议(至少如果我理解它应该做什么)
procedure OrderArrays(var ArrayNameValuePairs: array of TPair<string, string>);
begin
TArray.Sort<TPair<string, string>>(ArrayNameValuePairs,
TComparer<TPair<string, string>>.Construct(
function(const Left, Right: TPair<string, string>): Integer
begin
Result := Length(Right.Key) - Length(Left.Key);
end));
end;
正如您所看到的,我将名称和值组合在一起,因为它们显然属于一体。这使得对这个组合数组的排序变得更加容易,因为您不必对包含indizes的第三个数组进行排序以重新排序两个原始数组。