じゃんぬねっと日誌

ネタと雑記と時々プログラミング

目次

Blog 利用状況

ニュース

不況すぎる件。

スポンサードリンク

運営サイト

  • C# と VB.NET の入門サイト

書庫

CType と DirectCast の違い

VB.NET のキャストには CTypeDirectCast があります。
これらの違いを理解できていない方も多いようですので紹介したいと思います。

こういうものはすべて MSDN ライブラリ に答えがあります。

DirectCast (microsoft.com) からの引用

型変換の操作を示すキーワードです。次の例で示すように、CType キーワードと同様の方法で使用します。

どちらのキーワードも、1 番目の引数は変換の対象となる式で、2 番目の引数は変換後の型です。式のデータ型と 2 番目の引数で指定されているデータ型の間に変換が定義されていない場合は、どちらの変換も失敗します。

2 つのキーワードの違いは、CType は式と型の間に有効な変換が定義されてさえいれば成功するのに対し、DirectCast はオブジェクト変数のランタイム型が指定された型と同じである必要があります。ただし、指定した型と式のランタイム型が同じ場合、実行時のパフォーマンスは CType より DirectCast の方が優れています。

まあ、DirectCast の方がパフォーマンスが良いということなのですが、以下の場合は DirectCast ですとキャストに失敗するということです。

Dim oHoge       As Object  = 2.56                        ' Object 型に浮動小数を設定
Dim iCType      As Integer = CType(oHoge, Integer)       ' 成功する
Dim iDirectCast As Integer = DirectCast(oHoge, Integer)  ' 失敗する

上の例で、DirectCast は InvalidCastException という例外を Throw します。
一方、CType は、式と型の間の (暗黙的に) 変換が有効であれば成功します。

暗黙の型変換と明示的な型変換 (microsoft.com) からの引用

変換キーワードと共に使用する値は、変換先のデータ型で有効である必要があります。有効でない場合はエラーが発生します。たとえば、長整数型 (Long) を整数型 (Integer) に変換する場合は、その長整数型 (Long) の値が整数型 (Integer) の有効範囲内に含まれている必要があります。

たとえば、浮動小数の場合、暗黙的に整数型へキャストされた後に値の範囲内であれば、CType では成功するということですね。
DirectCast では、型を暗黙的に変換することはない (プログラマが指示した以外の暗黙的なキャストは行わない) ということです。(だから、例外が発生する)

ちなみに、私は CType は使用しないで、DirectCast を使用します。
暗黙的な変換は、バグの温床になると考えているからです。(型は曖昧でないことが望ましいですから)

投稿日時 : 2005年3月18日 12:00

コメントを追加

# re: CType と DirectCast の違い 2005/03/19 1:34 中博俊

惜しいなぁ。
もう一歩踏み込んで解説してほしい。

C#でいうと、CTypeはAs IsやらVBのConvert系でかなり幅広くフォローしようとする。
DirectCastは(int)なので、速い。
けっこういろんなことをVBコンパイラはやってますよ。(^^

# re: CType と DirectCast の違い 2005/03/19 3:54 菊池

Asは暗黙の変換しないでしょ>中さん

DirectCastがC#でのAs相当
CTypeがC#でのキャスト式


# re: CType と DirectCast の違い 2005/03/19 9:16 じゃんぬねっと

ところで CType ってインライン コンパイルでしたっけ?
違ったかなー。

# re: CType と DirectCast の違い 2005/03/19 10:21 おぎわら

ごさんこう~
Boxing,Unboxingの用語をつかうと解説しやすいっすよ

Dim l As Long = 30
Dim o As Object = l
Dim d As Double
Dim i As Integer
Dim l2 As Long

d = CType(o, Double) ' 成功 :
  'unboxing + Doubleへのwidening conversion
i = CType(o, Integer) ' 成功 :
  'unboxing + Integerへのnarrowing conversion

' ※C#のキャスト構文ではいずれも例外が発生
' × d = (double)o;
' ◎ d = (long)o;

' × i = (int)o;
' ◎ i = (int)((long)o);

d = DirectCast(o, Double) ' 失敗 :
'Doubleへのunboxingはできないため
i = DirectCast(o, Integer) ' 失敗 :
'Integerへのunboxingはできないため
l2 = DirectCast(o, Long) ' 成功 :
'実体がLongであるため

# re: CType と DirectCast の違い 2005/03/19 10:28 じゃんぬねっと

流石は名講師 (w
非常にわかりやすい...

# re: CType と DirectCast の違い 2005/03/20 1:26 中博俊

>Asは暗黙の変換しないでしょ>中さん
はいしません。
ぼけぼけ(^^;;
菊池さん時間遅いなー

ちょっとしか検証してませんが、CTypeはいろんなことをやってますね。
コンパイル後には存在が消えているので、付加逆圧縮ですね。(^^;;

# re: CType と DirectCast の違い 2005/03/20 9:31 じゃんぬねっと

「付加逆圧縮」ってなんですか? (w

# re: Boxing(キャスト)でも想定外の結果. 2006/07/24 1:15 Ognacの雑感

re: Boxing(キャスト)でも想定外の結果.

# re: CType と DirectCast の違い 2006/11/27 11:01 じゃんぬ

ちなみに、VB8 (VB2005) からは、TryCast が加わりましたから、C# の as 相当の仕組みができましたね。

# Cast 2007/10/11 7:06 Mr.Tの場所

Cast

タイトル  
名前  
URL
コメント