在Delphi中迭代变量

时间:2013-12-06 15:14:03

标签: delphi variables loops

鉴于声明:

Unit MyUnit;

interface

type

  TMyFileStream= class(TFileStream);
  ...
  end;

var
  a1,a2,a3,a4,a5: integer;
  b1,b2,b3: boolean;
  c1: char;
  d1,d2,d3,d4: TDateTime;
  f1,f2,f3,f4,f5,f6,f7,f8: TMyFileStream // LineX
  ...

procedure MyProc;

implementation

procedure MyProc
begin

  // I wanna iterate over all integer (or any other type) variables here with a loop regardless of their count and identifier name

end;

一些特定的类型变量会经常计算代码中的变化 - 大多数都会随着我添加新函数而增加。如何在循环中引用它们以对所有这些进行相同的操作?我想保留这样一个事实:当我添加一个新代码时,代码只需要在一个地方修改。

我已经考虑过把它们放在一个(静态的或动态的)数组中,但这涉及到引用它们的每个位置的代码修改,这是我想要多余的工作,如果它是无论如何都可能。

目前有38个变量我想接受一个acton,参考'的数量是远远高于100的倍数。

希望我足够清楚。 谢谢你的任何想法。

彼得

3 个答案:

答案 0 :(得分:5)

虽然设计有气味,但这就是指针:

type
  PMyFileStream = ^TMyFileStream;
  TMyFileStream= class(TFileStream)
  end;

var
  a1,a2,a3,a4,a5: integer;
  b1,b2,b3: boolean;
  c1: char;
  d1,d2,d3,d4: TDateTime;
  f1,f2,f3,f4,f5,f6,f7,f8: TMyFileStream; // LineX

function GetVarsInt: TArray<PInteger>;
begin
  result := TArray<PInteger>.Create(@a1, @a2, @a3, @a4, @a5);
end;

function GetVarsBool: TArray<PBoolean>;
begin
  result := TArray<PBoolean>.Create(@b1, @b2, @b3);
end;

function GetVarsChar: TArray<PChar>;
begin
  result := TArray<PChar>.Create(@c1);
end;

function GetVarsDateTime: TArray<PDateTime>;
begin
  result := TArray<PDateTime>.Create(@d1, @d2, @d3, @d4);
end;

function GetVarsMyFileStream: TArray<PMyFileStream>;
begin
  result := TArray<PMyFileStream>.Create(@f1, @f2, @f3, @f4, @f5, @f6, @f7, @f8);
end;

procedure HandleInt(var Value: Integer);
begin

end;

procedure HandleBool(var Value: Boolean);
begin

end;

procedure HandleChar(var Value: Char);
begin

end;

procedure HandleDateTime(var Value: TDateTime);
begin

end;

procedure HandleMyFileStream(var Value: TMyFileStream);
begin

end;

procedure MyProc;
var
  vInt: PInteger;
  vBool: PBoolean;
  vChar: PChar;
  vDateTime: PDateTime;
  vMyFileStream: PMyFileStream;
begin
  for vInt in GetVarsInt do
    HandleInt(vInt^);
  for vBool in GetVarsBool do
    HandleBool(vBool^);
  for vChar in GetVarsChar do
    HandleChar(vChar^);
  for vDateTime in GetVarsDateTime do
    HandleDateTime(vDateTime^);
  for vMyFileStream in GetVarsMyFileStream do
    HandleMyFileStream(vMyFileStream^);
end;

如果是TMyFileStream变量,当你只想操纵现有的对象实例时,你可能会没有指针。

答案 1 :(得分:2)

如果将这些变量放在一个类中,可以使用RTTI循环遍历该类的属性。我知道没有方法循环不属于类的变量。

答案 2 :(得分:0)

  

我已经考虑过把它们放在一个(静态的或动态的)数组中,但这涉及到引用它们的每个位置的代码修改,这是我想要多余的工作,如果它是无论如何都可能。

那是什么!做它!
你推迟修复可怕代码的时间越长,它就越糟糕。而且,它并不像你想象的那么糟糕。

E.g。更改以下内容:

var
  a1,a2,a3,a4,a5: integer;

为:

var
  A: array[1..5] of Integer;

现在所有引用a?的内容都无法编译(除非你有范围冲突,这在任何情况下都会是一场惨烈的灾难)。通过将a?更改为a[?],可以轻松修复这些编译错误。

如果你只是经历一个循环:compile --> fix --> compile --> fix --> ...你会发现你可以比你想象的更快地清理。