Delphi は、列挙型への整数の型キャストの範囲チェックまたは範囲外の例外発生を直接サポートしていません。参照:整数を列挙型に変換するにはどうすればよいですか? 列挙サブ範囲でインデックス付けされた配列の自動範囲チェックにより、これを回避しようとしています。私のテスト プログラムでは、RTTI を無効にし、名前付き列挙を持たないが型キャスト、Inc、Dec などでアクセスできる有効なサブ範囲値のテストを提供する非連続列挙を意図的に使用しました。
プログラムは、サブ範囲 (2) の非列挙要素を期待どおりに処理しますが、列挙配列の範囲外例外を生成しませんが、同等の整数インデックス配列の場合は生成します。これには正当な理由がありますか?整数のインデックス付き配列を使用して回避できますが、列挙インデックスはもう少し堅牢です。
type MyEnum = (zero,one,three=3);
var EnumCheck: array[MyEnum] of integer = (0,1,2,3);
var iEnum: integer;
var MyEnumVar: MyEnum;
var IntArray: array[0..3] of integer = (0,1,2,3);
procedure Test;
begin
{$R+}
MyEnumVar:= MyEnum (1); // One
iEnum := EnumCheck[MyEnumVar]; // OK - iEnum = 1
MyEnumVar:= MyEnum (2); // Out-of-bound
iEnum := EnumCheck[MyEnumVar]; // OK - iEnum = 2
MyEnumVar:= MyEnum (3); // Three
iEnum := EnumCheck[MyEnumVar]; // OK - iEnum = 3
MyEnumVar:= MyEnum (4); // Out-of-bound
iEnum := EnumCheck[MyEnumVar]; // no Exception; iEnum is set to random value
iEnum := 4;
iEnum := IntArray[iEnum]; // Exception thrown here
iEnum := IntArray[4]; // Compiler "subrange" error
end;
Delphi 10.4 update 2 の使用
編集:私は自分の仕事を見つけました。チェック配列を次のように定義します。
var iCheck: array[Ord(Low(MyEnum))..Ord(High(MyEnum))] of integer = (0,1,2,3);
期待どおりに範囲外の例外がスローされます。