- PR -

VB.NETで関数パラメータでのアップキャストとOption Strict Onについて

1
投稿者投稿内容
モチ
会議室デビュー日: 2004/03/03
投稿数: 2
投稿日時: 2004-03-03 20:16
初めて質問させていただきます、よろしくお願いします。

まず、簡素化した問題のコードを記述させていただきます。

言語:VB.NET
環境:Visual Studio 2003
コード:
Option Strict On

Class ClassA
    Private m_i As Integer = 1
    Public Function GetValue() As Integer
        GetValue = m_i
    End Function
End Class

Class ClassB
    Inherits ClassA
End Class

Module Module1
    Sub Main()
        Dim c As New ClassB
        WriteValue(c)           'NG:どうして?
        WriteValue(New ClassB)  'OK
    End Sub

    Sub WriteValue(ByRef c As ClassA)
        Console.WriteLine(c.GetValue())
    End Sub
End Module

コンパイルエラー:
Option Strict On で ClassA' から ClassB' への暗黙的な変換はできません。



メソッドWriteValueはClassAをパラメータに取り、値を出力する関数です、
そこにClassAを継承したClassBのインスタンスを渡そうと思いましたが、
Option Strict Onを指定するとコンパイルエラーが発生してしまいます。

ClassBはClassAのサブクラスなので、Option Strict Onが有ったとしても
拡大変換による暗黙のキャストされると認識していましたが、
VB.NETでは明示的な型変換が必要なのでしょうか?

そうしますと、NGの行の一つ下の括弧内でのNewの場合、コンパイルエラーにならない理由が
ちょっと納得いかない気もします。

お忙しいところお手数ですが、何か情報をお持ちのかたがいらっしゃいましたら
よろしくお願いいたします。
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2004-03-03 20:59
NAL-6295です。

率直に言えば、ByRefだから。

なのですが、なぜかというと
引数がByRefで参照型の場合、その変数が指し示しているオブジェクト自体、変更できてしまうという性質に基づいています。

コンパイルエラーはByrefであるがゆえ結果的に、ClassBの変数にClassAのインスタンスを暗黙では代入出来ないと言っているのです。

もし、変数が指し示すオブジェクト自体を変更する必要が無く、オブジェクトが持っているメンバを変更するだけで良い場合は、ByValで渡してあげると良いでしょう。



[ メッセージ編集済み 編集者: NAL-6295 編集日時 2004-03-03 21:01 ]
999
会議室デビュー日: 2003/05/17
投稿数: 14
投稿日時: 2004-03-03 22:36
暗黙的な変換に関して、親と子の関係を逆に解釈しているのでは。

>NGの行の一つ下の括弧内でのNewの場合、コンパイルエラーにならない理由が
>ちょっと納得いかない気もします。

定義と生成の型を考えれば、
Dim c As ClassA
c = New ClassB
WriteValue(c)

したがって、WriteValue(ByRef c As ClassA)の引数(定義)の型はClassAで、
生成の型はClassBだから、
WriteValue(New ClassB)
はコンパイルエラーにはなりません。

[ メッセージ編集済み 編集者: 999 編集日時 2004-03-03 22:41 ]

[ メッセージ編集済み 編集者: 999 編集日時 2004-03-03 22:51 ]
モチ
会議室デビュー日: 2004/03/03
投稿数: 2
投稿日時: 2004-03-04 09:31
返信ありがとうございます。

納得できました、

今回の場合、WriteValue関数内でパラメータのcに対して
新しいClassAのインスタンスを設定するという操作を考えた場合、
関数呼び出し時に渡されたクラスがClassAの派生クラスだったば場合、
関数の外から見るとダウンキャストになるということなんですね。

ByRefのことを勉強しなおしてきます、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)