I am new to vb.net, and this is my first project where I\'m fairly certain there is an obvious answer that I just can\'t find.
Problem: I have a l
Consider serialization. For this, a class is more in order than an old fashioned Struct:
<Serializable>
Class Animal
Public Property Name As String
Public Property Coloring As String
Public Property VaccinesUpToDate As Boolean
Public Property Species As String
Public Property DateOfBirth As DateTime
Public ReadOnly Property Age As Integer
Get
If DateOfBirth <> DateTime.MinValue Then
Return (DateTime.Now.Year - DateOfBirth.Year)
Else
Return 0 ' unknown
End If
End Get
End Property
' many serializers require a simple CTor
Public Sub New()
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0} ({1}, {2})", Name, Species, Age)
End Function
End Class
The ToString()
override can be important. It is what will display if you add Animal
objects to a ListBox
e.g.: "Stripe (Gremlin, 27)"
Friend animalList As New List(of Animal) ' a place to store animals
' create an animal
a = New Animal
a.Coloring = "Orange"
a.Species = "Feline" ' should be an Enum maybe
a.Name = "Ziggy"
a.BirthDate = #2/11/2010#
animalList.Add(a)
' animalList(0) is now the Ziggy record. add as many as you like.
In more complex apps, you might write an Animals
collection class. In that case, the List
might be internal and the collection could save/load the list.
Friend Sub SaveData(fileName as String)
Using fs As New System.IO.FileStream(fileName,
IO.FileMode.OpenOrCreate)
Dim bf As New BinaryFormatter
bf.Serialize(fs, animalList)
End Using
End Sub
Friend Function LoadData(fileName as String) As List(Of Animal)
Dim a As List(of Animal)
Using fs As New FileStream(fileName, FileMode.Open, FileAccess.Read)
Dim bf As New BinaryFormatter
a = CType(bf.Deserialize(fs), List(Of Animal))
End Using
Return a
End Function
XMLSerialization, ProtoBuf and even json are much the same syntax. For a small amount of data, a serialized list is an easy alternative to a database (and have many, many other uses, like a better Settings approach).
Notice that I added a BirthDate
property and changed Age
to calculate the result. You should not save anything which can be easily calculated: in order to update the Age
(or VaccinesUpToDate
) you'd have to 'visit' each record, perform a calculation then save the result - which might be wrong in 24 hours.
The reason for exposing Age
as a Property (rather than a function) is for data binding. It is very common to use a List<T>
as the DataSource
:
animalsDGV.DataSource = myAnimals
The result will be a row for each animal with each Property as a column. Fields
as in the original Structure
won't show up. Nor would an Age()
function display, wrapping the result as a readonly property displays it. In a PropertyGrid
, it will show disabled because it is RO.
So if a Structure using Properties will work, why use a Class instead? From Choosing Between Class and Struct on MSDN, avoid using a Structure unless the type meets all of the following:
Animal
fails the first 3 points (while it is a local item it is not a value for #1). It may also fail the last depending on how it is used.