質問

あと3日でVB.Net学習2ヶ月目という初学者です。
Sub Main() のみで基本事項の確認のみをしてきました。
ですから、フォーム、レポート、データベース、WEB関連の知識は完全にゼロ。
さて、その基本演習も最終段階に突入。
いよいよクラスです。

' ==============================
' クラスプログラミング; 演習3
' ==============================
Module theClass

  Sub Main()
    Dim T1 As New TEST1

    T1.Member1 = "T1.Member1"
    T1.Member2 = "T1.Member2"
    T1.BSave("D:\Temp\T1.bin", DirectCast(T1, Object)) <--- ?1
    T1.Member1 = "AAA"
    T1.Member2 = "BBB"
    Debug.Print(T1.Member1)
    Debug.Print(T1.Member2)
    T1.BLoad("D:\Temp\T1.bin", T1) <--- ?2
    If T1 IsNot Nothing Then
      Debug.Print(T1.Member1)
      Debug.Print(T1.Member2)
    Else
      Message("T1.bin は読み込めませんでした。")
    End If
  End Sub
End Module

?1=インスタンスを経由する共有メンバ、・・・へのアクセスです。正規の式は評価されません。
?2=Option strict on では、'ByRef' パラメータのオブジェクトの値を・・・縮小変換できませんでした。

Public Shared Sub BSave(ByVal aPath As String, ByVal aObject As Object)
  Try
    Using fs As New FileStream(aPath, FileMode.Create, FileAccess.Write)
      Dim bf As New BinaryFormatter

      bf.Serialize(fs, aObject)
      fs.Close()
    End Using
  Catch ex As IOException
    MsgBox(ex.Message & "(BSave)", MsgBoxStyle.Exclamation, "エラー:")
  End Try
End Sub

Public Sub BLoad(ByVal aPath As String, ByRef aObject As Object)
  If File.Exists(aPath) Then
    Try
      Using fs As New FileStream(aPath, FileMode.Open, FileAccess.Read)
        Dim bf As New BinaryFormatter

        aObject = bf.Deserialize(fs)
        fs.Close()
      End Using
    Catch ex As IOException
      MsgBox(ex.Message & "(BLoad)", MsgBoxStyle.Exclamation, "エラー:")
    End Try
  End If
End Sub

非共有の BSaveメソッドとBLoadメソッドのパラメータはファイルパスだけ。
共有メソッドの場合は、「何を」というのが必要かと思って2つ目のパラメータを追加。
もって、構造体の BSave と BLoad とに援用するテストをしたいと思っています。
し、しかし、上述の2つのエラーを前にどうしてよいか皆目わかりません。

>そのエラーを回避、もしくは発生させないためには次のように改造したらよい!

そういう回答等をお願いします。

通報する

回答 (1件)

?1:
Sharedなメソッドを呼び出すのですから,
インスタンス.メソッド
の形ではなく
型.メソッド
の形になります。
つまり,今回の場合は,
TEST1.BSave("D:\Temp\T1.bin", T1)
のように書く必要があります。
各クラスはSystem.Objectを暗黙の内に継承しているため,Objectへのキャストを書く必要はありません。

?2:
第2引数には,デシリアライズされたオブジェクトを代入するための,Object型の変数を指定します。
つまり,
Dim obj As Object = Nothing
T1.BLoad("D:\Temp\T1.bin", obj)
Dim T2 As TEST1 = TryCast(obj, TEST1)
If T2 IsNot Nothing Then
のような形になります。


ところで,Sharedの修飾がどう考えても逆に思えますが。
<Serializable> _
Public Class Test
 Public Sub Save (ByVal fileName As String)
  '自分自身をfileNameに保存する
 End Sub

 Public Shared Function Load (ByVal fileName As String) As Test
  'fileNameから読み込む
 End Function
End Class
のような形になるのが自然だと思います。
これだと,
Dim t As Test
として,
' 保存
t.Save("D:\Temp\t1.bin")

'読み込み
t = Test.Load("D:\Temp\t1.bin")
のように書くことになります。

この回答へのお礼

>共有メソッドはクラス名でアクセスする!

読み飛ばしていました。

>ところで,Sharedの修飾がどう考えても逆に思えますが。

BLOAD を共有にするのを忘れていました。
無用の混乱を与えてすみません!
ですから、以下の修正で成功しました。
本当にありがとうございました。

' ==============================
' クラスプログラミング; 演習3
' ==============================
Module theClass
  Sub Main()
    Dim T1 As New TEST1
    Dim obj As Object = Nothing

    T1.Member1 = "T1.Member1"
    T1.Member2 = "T1.Member2"
    TEST1.BSave("D:\Temp\T1.bin", T1)
    T1.Member1 = "AAA"
    T1.Member2 = "BBB"
    Debug.Print(T1.Member1)
    Debug.Print(T1.Member2)
    TEST1.BLoad("D:\Temp\T1.bin", obj)
    If T1 IsNot Nothing Then
      Debug.Print(TryCast(obj, TEST1).Member1)
      Debug.Print(TryCast(obj, TEST1).Member2)
    Else
      Message("T1.bin は読み込めませんでした。")
    End If
  End Sub
End Module

Public Sub BSave (ByVal fileName As String)
  '自分自身をfileNameに保存する
End Sub

これは非共有のメソッドとして書きました。
ただ、非共有と共有の共存については未だテストしていません。
本日が、クラス演習の初日なのでよく個も全体もわかっていません。
本当にありがとうございました。

このQ&Aは役に立ちましたか?0 件

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

新しく質問する

注目の記事

おしトピにAndroid版アプリが登場

話題のトピックにさくっとコメントできる「おしトピ」に Android版アプリが登場! もっと身近に使いやすくなりました。
今ならダウンロードで話題の掃除ロボットや全天球カメラが 当たるプレゼントキャンペーンも実施中。

このQ&Aを見た人が検索しているワード


新しく質問する

このカテゴリの人気Q&Aランキング

毎日見よう!教えて!gooトゥディ