トップ回答者
Shadows に関する不可解な現象

質問
-
Visual Studio 2008 Standar の Visual Basic
Visual Basic 2010 Exprss
Visual Studio Express 2012 for Windows Desktop の Visual Basic
で起きている問題なのですが ( OS は Windows7 Professional 64 bit )、
Module Module1 Sub Main() Dim d As New Derived() Dim s As String s = d.Test() Console.WriteLine(s) ' ↓なぜかビルドエラーにならず引数なしの Base.Test() が呼び出されるが、戻り値は明らかにおかしい。 ' ( 引数を "n" とすると、文字列 "Derived.Test()" の n 番目の文字を返しているようだ。) s = d.Test("1") Console.WriteLine(s) ' ↓数字に変換できない文字を渡すと InvalidCastException が発生する。 s = d.Test("A") Console.WriteLine(s) ' ↓こちらはビルドエラーになる。 'd.Test("1") End Sub End Module Public Class Base Public Function Test() As String Return "Base.Test()" End Function Public Function Test(ByVal s As String) As String Return "Base.Test(ByVal s As String):" & s End Function End Class Public Class Derived Inherits Base Public Shadows Function Test() As String Return "Derived.Test()" End Function End Class
のようなプログラムで、
s = d.Test("1") はビルドエラーになるはずだと思っているのですが、ビルドエラーにならず、実行すると "e" と出力されます。
また、s = d.Test("A") では InvalidCastException が発生します。
これは Visual Basic のバグでしょうか?
もし、これが仕様であるなら、s = d.Test("1") ではビルドエラーにならず、d.Test("1") だけだとビルドエラーになるのはどうしてでしょうか?
どなたか何か情報をお持ちの方いらっしゃいましたら回答をお願い致します。
回答
-
s = d.Test("1") はビルドエラーになるはずだと思っているのですが、ビルドエラーにならず、実行すると "e" と出力されます。
また、s = d.Test("A") では InvalidCastException が発生します。
これは Visual Basic のバグでしょうか?
バグかどうかはわかりませんが、メカニズムはこうだと予想されます。
d.Test で引数なしのメソッドを呼び出し、String 型のオブジェクトを得て、そのオブジェクトに対して (1) を実行しています。
String 型は配列のように扱え、s(1) だと s という String 型変数の 2 番目の文字を Char 型として返します。
Char 型は String 型に変換可能なので、2 番目の文字 'e' が、文字列 "e" になるのでしょう。
"A" がエラーになるのは、String(Integer) の引数の型に合わないからでしょうね。こういった暗黙な変換でわかりづらい現象を避けるには「Option Strict On」としていただく方が堅いでしょう。
もし、これが仕様であるなら、s = d.Test("1") ではビルドエラーにならず、d.Test("1") だけだとビルドエラーになるのはどうしてでしょうか?
どなたか何か情報をお持ちの方いらっしゃいましたら回答をお願い致します。
s(1) と書いて、代入先がない場合がエラーになるのと同じ理由でしょう。
意味的には「s = d.Test」と「s(1)」を二行にわたって書いたことと同じ扱いです。- 回答としてマーク NothingLastsForever 2013年9月25日 14:17
すべての返信
-
s = d.Test("1") はビルドエラーになるはずだと思っているのですが、ビルドエラーにならず、実行すると "e" と出力されます。
また、s = d.Test("A") では InvalidCastException が発生します。
これは Visual Basic のバグでしょうか?
バグかどうかはわかりませんが、メカニズムはこうだと予想されます。
d.Test で引数なしのメソッドを呼び出し、String 型のオブジェクトを得て、そのオブジェクトに対して (1) を実行しています。
String 型は配列のように扱え、s(1) だと s という String 型変数の 2 番目の文字を Char 型として返します。
Char 型は String 型に変換可能なので、2 番目の文字 'e' が、文字列 "e" になるのでしょう。
"A" がエラーになるのは、String(Integer) の引数の型に合わないからでしょうね。こういった暗黙な変換でわかりづらい現象を避けるには「Option Strict On」としていただく方が堅いでしょう。
もし、これが仕様であるなら、s = d.Test("1") ではビルドエラーにならず、d.Test("1") だけだとビルドエラーになるのはどうしてでしょうか?
どなたか何か情報をお持ちの方いらっしゃいましたら回答をお願い致します。
s(1) と書いて、代入先がない場合がエラーになるのと同じ理由でしょう。
意味的には「s = d.Test」と「s(1)」を二行にわたって書いたことと同じ扱いです。- 回答としてマーク NothingLastsForever 2013年9月25日 14:17