(私はすでにCodeReviewでこれを尋ねましたが、トピック外として閉じられました。うまくいけば、ここでトピックになります。)
派生型の静的配列 (LabelsA: array[0..3] of TLabel;
次のサンプル コードのように) と、基本型のオープン配列を受け入れるルーチン ( など) があり、それらの静的配列procedure DoSomethingWithControls(const AControls: array of TControl);
を呼び出したいと考えています。DoSomethingWithControls
私のサンプルを見てください:
procedure DoSomethingWithControls(const AControls: array of TControl);
var
i: Integer;
begin
for i := Low(AControls) to High(AControls) do
Writeln(AControls[i].Name);
end;
procedure Test;
var
LabelsA: array[0..3] of TLabel;
LabelsB: array[0..1] of TLabel;
procedure Variant1;
type
TArray1 = array[Low(LabelsA)..High(LabelsA)] of TControl;
TArray2 = array[Low(LabelsB)..High(LabelsB)] of TControl;
begin
DoSomethingWithControls(TArray1(LabelsA));
DoSomethingWithControls(TArray2(LabelsB));
end;
procedure Variant2;
type
TControlArray = array[0..Pred(MaxInt div SizeOf(TControl))] of TControl;
PControlArray = ^TControlArray;
begin
DoSomethingWithControls(Slice(PControlArray(@LabelsA)^, Length(LabelsA)));
DoSomethingWithControls(Slice(PControlArray(@LabelsB)^, Length(LabelsB)));
end;
procedure Variant3;
var
ControlsA: array[Low(LabelsA)..High(LabelsA)] of TControl absolute LabelsA;
ControlsB: array[Low(LabelsB)..High(LabelsB)] of TControl absolute LabelsB;
begin
DoSomethingWithControls(ControlsA);
DoSomethingWithControls(ControlsB);
end;
begin
Variant1;
Variant2;
Variant3;
end;
の呼び出しにはいくつかのバリエーションがありますDoSomethingWithControls
。
TArray1
バリアント 1 は非常に単純ですが、TLabel 配列のすべてのサイズのように「アダプター」型が必要です。もっと柔軟にしてほしい。バリアント 2 はより柔軟で統一されていますが、見苦しく、エラーが発生しやすくなっています。
バリアント 3 ( TOndrej 提供) はバリアント 1 に似ています - 明示的なキャストは必要ありませんが、バリアント 1 は、何かを台無しにした場合 (たとえば、コピーと貼り付け中に配列の境界が間違っている場合) に、コンパイラのセキュリティを少し強化します。
これらの欠点なしで (配列の要素型を変更せずに) これらの呼び出しを定式化する方法はありますか? D2007 および XE6 で動作するはずです。