我正在开发一个vb.net项目,用户可以在其中保存并打开二进制文本。 但问题是,在打开文件时,它返回一个对象而不是字符串和整数。
它返回Projectname.Classname 我希望它返回的是用户在保存文件时输入的名称和年龄。
这是我的代码:
''' <summary>
''' When the user clicks open
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
Try
If (openFileDialog1.ShowDialog = DialogResult.OK) Then
thefilename = openFileDialog1.FileName
Dim message = animalmgr.ReadFile(thefilename)
'Getting method from manager
If (Not (message) Is Nothing) Then
message.ToList().ForEach(Sub(msg) Resultlst.Items.Add(msg))
Else
UpdateResults()
End If
End If
Catch ex As Exception
MessageBox.Show(ex.ToString, "Error in opening file")
End Try
End Sub
经理类中的ReadFile函数:
''' <summary>
''' Reads a file from binary
''' </summary>
''' <param name="filename"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function ReadFile(ByVal filename As String) As Animal()
Dim BinSerial As BinSerializerUtility = New BinSerializerUtility
Dim animals = BinSerial.BinaryFileDeSerialize(Of Animal)(filename)
Return animals.ToArray
End Function
我在C#中做了完全相同的项目,但是我不知道为什么它在vb.net中不起作用。有谁知道这个问题以及如何解决它?
更新 BinSerializerUtility类
Public Class BinSerializerUtility
Public Sub BinaryFileSerialize(ByVal objs As List(Of Animal), ByVal filePath As String)
Dim fileStream As FileStream = Nothing
Try
fileStream = New FileStream(filePath, FileMode.Create)
Dim b As BinaryFormatter = New BinaryFormatter
For Each obj In objs
b.Serialize(fileStream, obj)
Next
Finally
If (Not (fileStream) Is Nothing) Then
fileStream.Close()
End If
End Try
End Sub
Public Function BinaryFileDeSerialize(Of T As {Class})(ByVal filePath As String) As List(Of T)
Dim list = New List(Of T)
If Not File.Exists(filePath) Then
Throw New FileNotFoundException(("The file" + " was not found. "), filePath)
End If
Dim fileStream = New FileStream(filePath, FileMode.Open)
Dim b As BinaryFormatter = New BinaryFormatter
While (fileStream.Position < fileStream.Length)
list.Add(CType(b.Deserialize(fileStream), T))
End While
Return list
End Function
End Class
动物类:
<Serializable()>
Public MustInherit Class Animal
Implements IAnimal
Private theCatagorytype As Categorytype
Private m_name As String
Private m_age As Integer
Private m_gender As String
Private m_id As Integer
Public Sub New(ByVal typ As Categorytype)
MyBase.New()
theCatagorytype = typ
End Sub
Public Sub New()
MyBase.New()
End Sub
#Region "Properties"
Public Overridable ReadOnly Property Description As String
Get
Return String.Format("{0}, {1}, {2}, {3}", Me.Id, Me.Name, Me.Age, Me.Gender)
End Get
End Property
Public Property Categorytype As Categorytype
Get
Return theCatagorytype
End Get
Set(value As Categorytype)
theCatagorytype = value
End Set
End Property
Public Property Id As Integer Implements IAnimal.Id
Get
Return m_id
End Get
Set(value As Integer)
If (value > 0) Then
m_id = value
End If
End Set
End Property
Public Property Name As String Implements IAnimal.Name
Get
Return m_name
End Get
Set(value As String)
m_name = value
End Set
End Property
Public Property Age As Integer
Get
Return m_age
End Get
Set(value As Integer)
m_age = value
End Set
End Property
Public Property Gender As String Implements IAnimal.Gender
Get
Return m_gender
End Get
Set(value As String)
m_gender = value
End Set
End Property
#End Region
Public MustOverride Function GetEaterType() As EaterType Implements IAnimal.GetEaterType
Public MustOverride Function GetSpecies() As String Implements IAnimal.GetSpecies
End Class
答案 0 :(得分:1)
我认为将Save
和Load
函数放在类本身中更有意义,而不是为操作编写类包装器:
' in Animal class:
Friend Shared Function LoadData(myFile As String) As List(Of Animal)
Dim newList As List(Of Animal)
If File.Exists(myFile) Then
Using fs As New FileStream(myFile, FileMode.Open)
Dim bf = New BinaryFormatter
newList = CType(bf.Deserialize(fs), List(Of Animal))
End Using
Else
'return empty list of there is no file
newList = New List(Of Animal)
End If
Return newList
End Function
这似乎比尝试一次读取一个对象并将其放在List中更简单。在组织上,如果Foo
,Bar
和Animal
都可以自行序列化和反序列化,则会减少实用程序类的数量。加载它们:
animals = Animal.LoadData(FileName)
' put animals in a ListBox:
myfrm.ListBox1.Items.AddRange(animals.ToArray)
比为列表框制作动物副本更好的方法是使用List(Of Animal)
作为DataSource
。这样,用户就可以看到代码所使用的相同数据集。
答案 1 :(得分:0)
将对象添加到列表框或下拉列表时,默认情况下使用ToString()
为您提供对象的字符串表示形式,类名称是默认的ToString()
实现。
如果您在ToString()
课程中覆盖Animal
,则会显示您需要的内容。
编辑这假设您真的希望您的ReadFile
方法返回Animal
个对象的集合,并且您希望将实际对象添加到列表框而不是真正的将字符串表示添加到列表框中。