文法?について教えてください
type
TMyMode = (
mmNormal1,
mmNormal2,
mmNormal3
);
TMyModeEx = (
mmNormal1, ←
mmNormal2, ← この部分にTMyModeの要素を含めたい
mmNormal3, ←
mmExpert1,
mmExpert2
);
クラス派生のようにメンバ(要素)を増やして再定義したいのです。
皆さんならどういたしますでしょうか?
柴田さん:
> クラス派生のようにメンバ(要素)を増やして再定義したいのです。
> 皆さんならどういたしますでしょうか?
> type
> TMyMode = (
> mmNormal1,
> mmNormal2,
> mmNormal3
> );
>
> TMyModeEx = (
> mmNormal1, ←
> mmNormal2, ← この部分にTMyModeの要素を含めたい
> mmNormal3, ←
> mmExpert1,
> mmExpert2
> );
私なら、拡張される可能性があるものには列挙型を使わないようにします。
type TMyMode=LongInt;
const mmNormal1=$0001;
mmNormal2=$0002;
mmNormal3=$0003;
type TMyModeEx=TMyMode;
const mmExpert1=$0101;
mmExpert2=$0201;
列挙型は、とどのつまり値の意味づけです。 上記の書き方であれば、
何となく型や、値の変域を継承しているように見えますので、目的は
達成できます。 $???? の部分は、値が重複しないようにしてください。
#わざと値を重複させて複数の意味を持たせるというテクニックも
ありますが、今回は割愛します。
ちなみにもとの TMyMode の定義に手を入れることができない場合……
type TMyMode=(mmNormal1,
mmNormal2,
mmNormal3);
type TMyModeEx=TMyMode;
const mmExpert1=TMyModeEx($0101);
mmExpert2=TMyModeEx($0102);
……などとしても似たようなことはできます。
――――――――――――――――――――――――――――――――――――
株式会社イマジオム 代表取締役 高木太郎
〒316-0024 茨城県 日立市 水木町 1-11-10
電話:0294-28-0147
ファクシミリ:0294-28-0148
電子メール:tarou_...@imageom.co.jp
ホームページ:http://www.imageom.co.jp/
コンパイラを改造しないと無理なようですが
代替案として、こんなんどうですか
TOrigMode =
(
mmNormal1 = 1,
mmNormal2 = 2,
mmNormal3 = 3,
mmExpert1 = 4,
mmExpert2 = 5
);
TMyMode = mmNormal1..mmNormal3;
TMyModeEx = mmNormal1..mmExpert2;
ちなみに、列挙型は、ファイルに書き出す時のことを考慮して
数値を明示しておいたほうが無難かと思います
また、列挙型の数値のサイズは、自動的に決定
されるようで、
上の場合
aa :TMyMode;
と宣言すると
1バイトが確保されるようです
コンパイラオプション
$MINENUMSIZE 4
を使用してサイズを調整するか
ダミーで列挙変数を下のように宣言すると
TOrigMode =
(
mmNormal1 = 1,
mmNormal2 = 2,
mmNormal3 = 3,
mmExpert1 = 4,
mmExpert2 = 5,
mmDmmy = $7FFFFFFF
);
とでもすると
4バイトが確保されます
高木さん、狐小僧太郎吉さん
列挙型の要素って ただの変数名だったんですね
理解できました。
おかげさまで綺麗なコードが書けそうです。
有難うございました
というのも
列挙型は、配列のインデクスとしても使用できますが、
例えば
aa :array[TOrigMode] of integer;
と宣言し
var ii :TOrigMode;
for ii := Low(TOrigMode] to High(TOrigMode) do
begin
aa[ii] := ~;
end;
という使い方ができますが
上の宣言例のように
mmDummyを指定すると
コンパイラにmmExpert2 から mmDumy
の間に要素があると見なされて
上の配列が巨大な大きさになります。
サイズの確保のために mmDummywo
を使うのは避けたほうが良いようで
また数値を明示する場合は
配列のインデクスに使用するかどうか
一考の余地が必要なようです
>サイズの確保は $MINENUMSIZEのみを
>使用したほうが良いようです。
今回は Delphi2005 for.Net と Delphi5の
混在開発の為、Delphi5に合わせ(列挙値の設定不可らしいです)
狐小僧太郎吉さんの案を元に
TOrigMode = (
mmNormal1,
mmNormal2,
mmNormal3,
mmExpert1,
mmExpert2
);
TMyMode = mmNormal1..mmNormal3;
TMyModeEx = mmNormal1..mmExpert2;
とさせて頂き、GetEnumName や GetEnumValue 等も使う予定です
このまま 列挙値の設定はしない方向ですが
問題ございますでしょうか?
問題ないでしょう
どこかで、明示的に宣言しておかないと
プログラム修正したときに、うっかり変わってしまい
実行環境を記録したINIファイル等を
設定するときに使っていると
往生をこきます。
整数値に対応させるには、
いくらでも代替案はあります。
例えば、配列を使って
aa :array[TOrigMode] of integer = (1,2,3,4,5);
とやって、対応させるとか
こっちの方がええかもね
(ちょっち、めんどくさいか)
aa :array[TOrigMode] of integer = (10,20,30,40,50);
とか、+10ずつにするとかできますからな。
ちなみに、私は、Delphi7を使用しております
Delphi2005はインストールしてますが
使ってません。
GetEnumName GetEnumValue については知らなかった
しかし、上のように普通に宣言して
GetEnumName(TypeInfo(TOrigMode),Ord(mmNormal3));
と書いても
「型情報を持ってません」
とか、エラーが出て使えませんが
VCLで定義してある
TAlignment,TLabelPosition
については、文法エラーがでないで
GetEnumName が使えます。
、VCLのソースを見ても
普通にENUM定義してあるだけなのに
??????????
どないなってんねん
違いが見えない