あと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:
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
これは非共有のメソッドとして書きました。
ただ、非共有と共有の共存については未だテストしていません。
本日が、クラス演習の初日なのでよく個も全体もわかっていません。
本当にありがとうございました。
お礼
>共有メソッドはクラス名でアクセスする! 読み飛ばしていました。 >ところで,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 これは非共有のメソッドとして書きました。 ただ、非共有と共有の共存については未だテストしていません。 本日が、クラス演習の初日なのでよく個も全体もわかっていません。 本当にありがとうございました。