id:Schima:20090228 で、C++/CLIにてinitonlyにより定数っぽいもの(readonly)を定義する方法をご紹介しましたが、やはり厳密な意味での定数ではないために困ることがあります。この方法では、コンパイル時に定数が必要な場合には使えません。
例えばenumの初期値にはconstな値が必要です。よって、以下のコードはコンパイルが通りません。
// C++/CLIで定数の定義 public ref class Const abstract sealed { public: static initonly Int32 Hoge = 111; };
// C#でenumの定義 enum MyEnum { Hoge = Const.Hoge // 定数が必要なのでダメ }
そこで、また新しいキーワードliteralを使います。意味は読んで字のごとくです。C++/CLIはずいぶんと未知のキーワードや機能があって、いつも見つけるたびに驚きの連続です。
ただし、このliteralなフィールドにstaticは付けられません。これが結構厄介で、そうするとstaticクラス、すなわちC++/CLIでいうところのabstract sealedなクラスにはliteralフィールドは定義できないようです。
以下のように記述すると、「シールされた抽象クラスはインスタンス メンバ 'Hoge' を含むことはできません」というメッセージが出ます。
public ref class Const abstract sealed { public: literal Int32 Hoge = 111; };
しぶしぶabstractかsealedかどっちか片方を取ればコンパイルは通ります(たぶんsealedを取るほうがまだましかと)。
public ref class Const abstract { public: literal Int32 Hoge = 111; };
これをC#から定義を見ると、public const intな定数となっているのが確認できます。