久々にC#な話題
最近目にした中で使っていなかったなと思ったキーワード
まずreadonly
これは初期化構文以外にもコンストラクタでも代入可能, 実行時に初期化するので, そのオブジェクトが作られた時間なんかも表現できる(使うかどうかは置いておいて)"実行時"定数フィールドを作る修飾子
constが"コンパイル時"定数を作るのと違ってコンストラクタやメソッド呼び出しが要る値型や参照型の定数と言うと語弊があるが, 此処で作っているのはCの"const T *"ではなくて"T * const", 参照先の状態を変えるようなメソッドを呼んだり, フィールドを書き換えたりはできる参照型の定数を作ることができる
constとは違ってコンパイル時の最適化には直接影響しないけど, 実際に.NETの多くの値型にあるEmptyフィールドなんかはpublic static readonly(特にpublicな)staticなフィールドはそのクラス変数が何かの拍子にカチャカチャ変わるというのも恐い殆どがreadonlyとなるはずで, 特に忘却の彼方にすっ飛んだ or 他人の書いたコードを利用する時とかに, それでもそんなに酷いことはしないとは思いたいのですが変なところで余計な変更の影響を受けずに済むというのはコード管理上便利かもしれないかなと思ってみたり
次にas
これはobjectやインタフェース型, 継承元クラス型の引数や戻り値から目的の方へのキャスト, つまりは参照変換に使える演算子
キャストが上手くいけば目的のオブジェクト, 失敗すればnullが返って来る仕掛け
こっちは『中身』を見て変換先に合うように文字通り『変換』操作を行う普通の整数, 浮動小数間のキャストとかとこっちはあくまでもコード上のコンパイル時の型を指定するもの, 実行時型は元から変換先(かそのさらに特化された型)であって, 内部構造に手を加えるわけではない参照変換は似て非なるものなので, そういうのをよほど危険なことをやらない限りはInvalidCastExceptionなんて吐かれるコードは書かないだろうからその上では意味的に等価, 上手くいけばエラー処理をnullと一緒にできる分簡潔に書けるかも記述上で区別するのには便利そう
しかしながら, ヘルプによると任意の値型からobject型への変換, ICollectionとかTagプロパティに突っ込んだりする時に使う, 気分はC言語の単項*演算子(型情報もついてくるので厳密には違うけど)ボックス化変換もできるって書いてあるけど, 明示的にobjectにキャストする必要なんてまず出てこないから, 結局は参照変換にしか利用出来ない, これでボックス化されたobjectを元の値型に戻す変換, 気分はC言語の単項&演算子ボックス化解除変換にも使えれば書き分けという意味では完璧なんだけど, 残念ながら値型にはnullがないので無理なのよね, 本当にむずがゆい気分
以前に書いていた記述が間違っていたのに気がついたので訂正, 何かおかしいと腑に落ちないでいたんだけどなぁ… やっぱり違ったか
注: 以下のリンクはVisual Studio .NET 2003のHTMLヘルプへのリンクですので, Visual Studioが入っていない環境では表示できません, もしかしたらIEじゃないと表示出来ないのかもしれません
.NET Framework 開発者ガイド: プラットフォーム呼び出しのデータ型
これを読んだ限りではBOOLはSystem.Int32にマップされるのですが, これは既定のマップであって, ちゃんとSystem.Booleanにマップする方法もあったり
.NET Framework 開発者ガイド: Boolean 型に対する既定のマーシャリング
ということで次のようなアンマネージCヘッダを持つAPI, MessageBeepは
BOOL MessageBeep( UINT uType // サウンドタイプ );
次のようなC#コードに直してあげるのが正解のようで…
[DllImport("User32")]
[return: MarshalAs(デフォルトは2byte(16bit)のVariantBool(VB6のBoolean形式やCOMで使われる)で, これだと恐らくまずい(BOOLはCのセマンティクスのブール値で32bit型)UnmanagedType.Bool)]
private static extern bool MessageBeep(uint uType);
同様に引数の方のUINTも同一サイズの型を利用できる規則を使ってintにすればunsignedのくせに-1を要求する謎仕様にも対処できるのですが, こっちはプロトタイプを尊重してこのまま放置することに
微妙に喉につかえていた骨が取れたようなあんまり取れていないようなといった感じではあるが, こんなもんで
ま, 戻り値の方はどうせ捨てているのでどっちでも良いんですが…
ということで この辺 + 上のTopic関連 + α の修正を加えたIllust Logic Paintを忘れなければUpしておこうと思っています