VB.NETには例えばDoubleの値をIntegerにしたい場合、2つの方法があります。
速度が違うのかなー、と思ったらそうでもないみたい。
以下、引用。
DirectCastのILコードはunboxでアンボクシング(値型と参照型の変換)だけを行っているようです。CType、CIntの方は変換用のメソッドが呼び出されているよう です。(中略)少なくともCInt(o)とCType(o , Integer)はILコードレベルでは等価なようです。
ILコードレベルで等価なら、速度はかわんないだろうなー。
しかしJavaやC#から先にやっている身としては、どうにもCInt()なんてのは気持ち悪いな。 CIntなんてのはVB6時代由来もので、互換性のために(というかプログラマが新しいことを覚えなくていいように?) 残されているような気もするけどなぁ。 うん、特に理由がなければCTypeで書くようにしよう。
CTypeよりもDirectCastの方が速いんですって。
理由は、CTypeが内部的に「VisualBasic.なんちゃらかんちゃら」(「Visual Basic のランタイム ヘルパー ルーチン」とかいうらしい)を使っているのに対して、DirectCastは使っていないかららしい。
じゃあ、CTypeなんか使わずにDirectCastすればいいじゃん! …なんつって、次のようなコードを書くと…
Dim a As Integer = DirectCast(3.14, Integer)
エラーになりますね。
Dim a As Integer = CType(3.14, Integer)
ならOK。
ガッデム、なぜだ!…それは、DirectCastの方が守備範囲が狭いからだそうです。IntegerとかDoubleへはCTypeじゃないと変換できないみたい。
結局、「DirectCastでいけるところはDirectCastで、それ以外はCTypeで」ってのがお利口さんなコーディングスタイルってことでしょうかね。
最近知ったんですけど、VB.NETってC#と違ってStringをIntegerにキャストしちゃったりできるんですね。
Option Strict On にしていても関係ないらしい。
Dim a As Integer = CType("123", Integer) Dim b As Integer = CInt("123") Console.WriteLine(a + b)
上記を実行すると、エラーにならずにコンソールに「246」と表示されます。
なんとおぞましい。
まあでも、やっぱりInteger.Parse()やらInteger.TryParse()を使った方がいいみたい。 ひとつには動作速度。なんと10倍もParseの方が速いらしい。
参考
2つめには、やっぱ値を厳密に処理してくれることかなぁ。 この点はソースを探すのがめんどくさいのでまた今度。
こんな記事発見。
これは「銀行丸め」ってやつですね!
最近人から教わって知った!
どっちか一方向にばかり丸めると誤差が大きくなって、そりゃカネを扱うシステムにはキケンだってんで、 バランスをとるために「奇数のときは上方、偶数のときは下方」に丸めるという。
これもVB6時代の名残とのこと!
VB.NETでこの手の計算処理を書くときは注意が必要ですね。