none
String型・配列型・構造型の定義に対する初期化について RRS feed

  • 質問

  • String型・配列型・構造型の定義に対する初期化について、VB6とVB.NETを比べると、以下のようになると理解しています。

    ・VB6では、宣言時に初期化されている
    ・VB.NET化において、宣言時に何も指定していなければ、Nothingとしてセットされる

    このため、VB.NETでは、意図的にInitializeしないと、後続の処理で何もセットされていない状態で、変数を引渡しすると、異常終了する場合があります。

    そこで、VB.NETでは、String型・配列型・構造型の定義に対する初期化について、構造体を呼出す側の関数上でNothingのまま、後続の処理で値がセットされない警告メッセージを拾って初期化を追加することで回避できるのものか、値がセットされていても、異常終了する場合があるのか?
    また、構造体のように無視できない大きさ(サイズ)に対し、初期化のロジックを入れた場合のパフォーマンスやメモリへの影響などがあるのか?
    こういった疑問点について、教えていただきたく、お願いいたします。

    2010年2月23日 7:07

回答

  • 外池と申します。

    非常に微妙なところですね。まず、簡単なものからですが・・・・、

    配列型は、おっしゃるとおり、Nothingのままになってしまいます。このような状態で特定の要素にアクセスしようとすると例外が発生します。この例外をCatchして初期化するような対症療法的なプログラミングのロジックも可能かな、とは思います。(「思います」というだけで、私ならやりません)

    構造型については、何か誤解があると思います。構造体は「値型」なので、基本的に放っておいてもデフォルト値で初期化されます。ただ、構造体の中にメンバー変数が参照型なら、そのメンバー変数はNothingになりますね。

    最後に、

    String型は参照型ですがややこしいです。変数sを定義だけした(初期化しない)状態で、s=Nothingの比較はTrueを返しますし、s=""の比較もTrueを返します。どのような考え方になっているかは、仕様を記述したMicrosoft社の資料を確認することをお奨めします。

    いずれにせよ・・・・、

    ちゃんとしたドキュメントをひととおりチェックされることが大事かと思います。
    (ホームページを再開しました)
    • 回答としてマーク masakiy 2010年2月23日 17:37
    2010年2月23日 8:06

すべての返信

  • 「構造型」って 「構造体」 のことだと思いますが、これについて言わせて頂くなら
    .NET の構造体は値型ですので、

    > ・VB.NET化において、宣言時に何も指定していなければ、Nothing としてセットされる

    ということはありません。たとえば以下のような構造体があったとして、

    Structure Kozotai
      Public A As Integer
      Public B As Double
      Public C As String
    End Structure

    Dim _kozotai As Kozotai

    と宣言した時点で、構造体のインスタンスは生成されています。

    ただし構造体のメンバに String 等の参照型があるなら、Nothing のままです。

    Dim _kozotai As Kozotai
    Dim i As Inteegr = _kozotai.A ← これは 0
    Dim s As String = _kozotai.C  ← これは Nothing
     
    値型と参照型の違いについて、詳しくは以下の記事をご覧ください。
    (.NET では 構造体は VB も C# も同じです)
    http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_005/cs2_005_03.html
    http://ufcpp.net/study/csharp/oo_reference.html#abst


    2010年2月23日 7:49
    モデレータ
  • 外池と申します。

    非常に微妙なところですね。まず、簡単なものからですが・・・・、

    配列型は、おっしゃるとおり、Nothingのままになってしまいます。このような状態で特定の要素にアクセスしようとすると例外が発生します。この例外をCatchして初期化するような対症療法的なプログラミングのロジックも可能かな、とは思います。(「思います」というだけで、私ならやりません)

    構造型については、何か誤解があると思います。構造体は「値型」なので、基本的に放っておいてもデフォルト値で初期化されます。ただ、構造体の中にメンバー変数が参照型なら、そのメンバー変数はNothingになりますね。

    最後に、

    String型は参照型ですがややこしいです。変数sを定義だけした(初期化しない)状態で、s=Nothingの比較はTrueを返しますし、s=""の比較もTrueを返します。どのような考え方になっているかは、仕様を記述したMicrosoft社の資料を確認することをお奨めします。

    いずれにせよ・・・・、

    ちゃんとしたドキュメントをひととおりチェックされることが大事かと思います。
    (ホームページを再開しました)
    • 回答としてマーク masakiy 2010年2月23日 17:37
    2010年2月23日 8:06
  • ちょっとだけ補足。
    VB の Nothing キーワードは C# における null と同義ではなく、default(T) に相当します。つまり値型の場合「全てのメンバが既定値 (0/null) で初期化されたインスタンス」を指すことになります。参照型における Nothing は C# の null と同等です。
    この点を意識していないと会話がすれ違ったりするかも知れません。
    2010年2月23日 8:14
  • ちょっとだけ補足。
    VB の Nothing キーワードは C# における null と同義ではなく、default(T) に相当します。つまり値型の場合「全てのメンバが既定値 (0/null) で初期化されたインスタンス」を指すことになります。参照型における Nothing は C# の null と同等です。
    この点を意識していないと会話がすれ違ったりするかも知れません。

    なるほど!これは紛らわしい話ですね!!補足ありがとうございます。

    # default(T) は知らなかった。あぶないあぶない・・・(汗

    この辺の話に関する記事を見つけたので、一応参考までに挙げておきます。

    http://blogs.wankuma.com/torikobito/archive/2007/10/10/101081.aspx
    2010年2月23日 8:40
    モデレータ