なぜtypeinfoにはtypeinfoがありません”列挙型のエラー
質問
最初のメンバーに通常の0(ゼロ)ではなく1(1)の順序値を持たせたい次の列挙型を宣言しました:
type
TMyEnum = (
meFirstValue = 1,
meSecondValue,
meThirdValue
);
TypeInfo()を呼び出すと、 GetEnumName()の呼び出しの一部として、コンパイラエラーが表示されます:
GetEnumName(TypeInfo(TMyEnum), Ord(aValue));
エラー:" E2134:タイプ 'TMyEnum'にはtypeinfoがありません"
これはなぜですか?
クラスが $ M コンパイラオプションを有効にしてコンパイルされた場合、または( TPersistent などのクラスから派生)クラスがtypeinfoしか持たないことを知っていますが、列挙型のtypeinfoを持つための特別な条件はないと考えていました。
解決 2
特定の順序値が割り当てられている列挙型では、型情報はサポートされていません。列挙型メンバーは、コンパイラーによって通常割り当てられる順序値とは異なる順序値を持ちます。
特定の値が必須または望ましい場合、「未使用」列挙型メンバーは「パッド」に挿入する必要があります。必要に応じて列挙型。例(強調のみを目的とした追加のインデント):
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue
);
サブレンジを使用して、「フィルタリング」することができます。未使用の初期値を取り出します:
TValidMyEnum = meFirstValue..meThirdValue;
その後、元の列挙型の名前を変更して、プロジェクト全体でサブレンジ型を使用できるようにすることを検討できます。
列挙に" gaps"が含まれている場合、サブ範囲は十分ではありません:
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue,
meNOTUSED2,
meFinalValue {= 5}
);
この場合、未使用のメンバーを除外するためにコンパイル時の範囲チェックを拡張する単純な方法はありませんが、いくつかのセット型により、必要な runtime チェックを実装するビジネスが簡素化されます:
type
TMyEnums = set of TMyEnum;
const
meNOTUSED = [meUNUSED1, meUNUSED2]; // .. etc as required
meValidValues = [Low(TMyEnum)..High(TMyEnum)] - meNOTUSED;
if NOT (aValue in meValidValues) then
// etc
他のヒント
不連続な列挙およびゼロから始まらない列挙にはtypeinfoがありません。 typeinfoを実装するには、下位互換性の問題のため、既存のtkEnumerationとは異なる形式である必要があります。
Delphi 2010にtkDiscontiguousEnumeration(または、より適切な名前のメンバー)を実装することを検討しましたが、相対的な不足と列挙の難しさを考慮すると、利点は小さいように見えました。いくつかのエンコーディングは、いくつかのシナリオではより良く、他のシナリオではより悪いです。