beginner question about classes

M

me

Hi All,

I am new to Classes and learniing the ropes with VB.NET express

Here's my question - say I have a want to manage a list of books.
Each book has an Author, Title and ISBN

Now, I am used to using Arrays so I would normally do something like this:

Set an array up during the init routine (called from form_load) say of
Books(100) of type Book (which is setup with Author as string, Title as
string etc.)

Allow the user to add/delete/edit a new book (with a simple VB form)

When it comes to saving the file, just cycle through the array and dump each
line to a CSV text file.

Opening - again cycle through the CSV file and fill the array.

Now - here's my question:

How can I do this using classes? I have set up a class (called Book) with
properties such as Title, Author, ISBN and can get/set them

I create a new instance, i.e. myBook = New Book.Book

However, I now dont understand.... This creates one instance, which i can
fill with information. However, if i want another book, I have to create

myBook2 = New Book.Book

So how does one then cycle through these items when saving? How do we create
all the instances when first loading the CSV file?

I tried myBook(1000) = New Book.Book but got an error.

I tried using

myBookGroup as Collections

but still... I dont understand - how can I refer to each individual book in
a loop for example when reading/writing the file?

Am I misunderstanding the point? Should I just stick with arrays?

Thanks






now I can create a collection
 
A

Armin Zingler

me said:
Hi All,

I am new to Classes and learniing the ropes with VB.NET express

Here's my question - say I have a want to manage a list of books.
Each book has an Author, Title and ISBN

Now, I am used to using Arrays so I would normally do something like
this:

Set an array up during the init routine (called from form_load) say
of Books(100) of type Book (which is setup with Author as string,
Title as string etc.)

Allow the user to add/delete/edit a new book (with a simple VB form)

When it comes to saving the file, just cycle through the array and
dump each line to a CSV text file.

Opening - again cycle through the CSV file and fill the array.

Now - here's my question:

How can I do this using classes? I have set up a class (called Book)
with properties such as Title, Author, ISBN and can get/set them

I create a new instance, i.e. myBook = New Book.Book

However, I now dont understand.... This creates one instance, which
i can fill with information. However, if i want another book, I have
to create

myBook2 = New Book.Book


If your array's name is 'Books', you can store the reference to a new book
directly in this array:

Books(Index) = New Book.Book

Now the item at position Index points to the book that has been created in
the same line.

'Index' is a variable that you will have to manage. It should point to the
first empty position within the array. At the beginning, the value of Index
is 0. After you stored a reference to a new book at the position that Index
points to, Index has to be incremented by 1, so next time you will store a
new book at the next position in the array. There are alternatives better
than arrays that I'll mention below.

After this, you can set the book's properties:

Books(Index).Title = ...
Books(index).author = ...

Or, if you have many properties:

With Books(Index)
.Title = ...
.author = ...
End With

So how does one then cycle through these items when saving? How do
we create all the instances when first loading the CSV file?

I tried myBook(1000) = New Book.Book but got an error.

I tried using

myBookGroup as Collections

but still... I dont understand - how can I refer to each individual
book in a loop for example when reading/writing the file?

Am I misunderstanding the point? Should I just stick with arrays?


Using arrays and classes is not a contradiction. BTW, an array is class,
too.

To loop through all books in the array:

For i as integer = 0 to index - 1
Debug.writeline(books(i).title)
Debug.writeline(books(i).author)
next i

You see how to access the books in the array and how to access the
properties. You can access them the same way if you write them to a file. I
don't know how you do it, thus I use debug.writline here.

There are alternatives:

For i as integer = 0 to index - 1
dim LoopBook as book
LoopBook = books(i)
Debug.writeline(LoopBook.title)
Debug.writeline(LoopBook.author)
next i

or

For i as integer = 0 to index - 1
with books(i)
Debug.writeline(.title)
Debug.writeline(.author)
end with
next i


Now we come to how to read the books from the file. I don't know how exactly
you intend to read the file, thus I focus on creating the objects and
storing them in the array:


index = 0

do until end-of-file
dim Author, Title as string
'read one line and store the values in 'Author' and 'Title'
'...

books(index) = new book
books(index).title = title
books(index).author = author
index += 1
loop


As you see, using an array can be much work:

- You can not change the size of an array. If you need more/less items, you
have to create a new array and copy the content of the old array into the
new one (ReDim Preserve).

- If you define your array being able to hold 100 items maximum, you need an
additional variable, called 'Index' in this example, that tracks the number
of items that are used within the array.

- You can not delete items from the array. You would have to copy items to
avoid having an unused item in the array. An unused item is 'Nothing', i.e.
it does not point to a book.

- If, within the array, unused items are allowed, you would have to loop
through all the items if you want to find an unused item where you can store
the reference to a new book.


Therefore, you'd better use another sort of collection. An arraylist is
often used. See the namespace System.Collections for more information. With
an arraylist, you can add and remove items without caring about the space
for new/removed items.

dim books as new arraylist

To add a new book - also when reading the file:

dim b as book

b = new book
b.title = ...
b.author = ...

books.add(b) 'add the book to the arraylist

Use books.RemoveAt (or books.remove) to remove a book from the arraylist.
Use the arraylist's count property to get the number of items in the list.
As an arraylist can contain references to any type of object, the type of
the arraylist's 'Item' property is 'Object'. For this reason, you have to
use type casting:

dim b as book

b = directcast(books(17), book)
debug.writline(b.title)
debug.writline(b.author)



See also:
http://msdn.microsoft.com/library/en-us/vbcn7/html/vaconManagingGroupsOfObjects.asp

http://msdn.microsoft.com/library/en-us/cpguide/html/cpcongroupingdataincollections.asp

http://msdn.microsoft.com/library/en-us/vbcon/html/vbconComponentsThatContainOtherComponents.asp
(especially: "Walkthrough: Creating Your Own Collection Class")


(As I see now, the links contain already all you need. :)


Armin
 
A

_AnonCoward

:
: Hi All,
:
: I am new to Classes and learniing the ropes with VB.NET express
:
: Here's my question - say I have a want to manage a list of books.
: Each book has an Author, Title and ISBN
:
: Now, I am used to using Arrays so I would normally do something like this:
:
: Set an array up during the init routine (called from form_load) say of
: Books(100) of type Book (which is setup with Author as string, Title as
: string etc.)
:
: Allow the user to add/delete/edit a new book (with a simple VB form)
:
: When it comes to saving the file, just cycle through the array and dump
: each line to a CSV text file.
:
: Opening - again cycle through the CSV file and fill the array.
:
: Now - here's my question:
:
: How can I do this using classes? I have set up a class (called Book) with
: properties such as Title, Author, ISBN and can get/set them
:
: I create a new instance, i.e. myBook = New Book.Book
:
: However, I now dont understand.... This creates one instance, which i can
: fill with information. However, if i want another book, I have to create
:
: myBook2 = New Book.Book
:
: So how does one then cycle through these items when saving? How do we
: create all the instances when first loading the CSV file?
:
: I tried myBook(1000) = New Book.Book but got an error.
:
: I tried using
:
: myBookGroup as Collections
:
: but still... I dont understand - how can I refer to each individual book
: in a loop for example when reading/writing the file?
:
: Am I misunderstanding the point? Should I just stick with arrays?
:
: Thanks


Here is one approach. Note that I'm ultimately defining an array of Book
objects and I'm using the ArrayList method for generating that array. This
isn't the approach I'd use in a real project - rather, I'd use a class that
inherits from CollectionBase. However, I don't have time to develop that for
you which is why I put together this example. I recommend you read up on the
CollectionBase class as well as Generics if you're using version 2.0 of the
framework (VB 2005).


'-------------------------------------------
'here are the namespaces we'll be using
'-------------------------------------------
Imports System
Imports System.Collections
Imports System.Io


'-------------------------------------------
'Define a function that reads a file and returns an array
'of book objects
'-------------------------------------------
Private Function GetBooks(FilePath As String) As Book()

'this is the object we'll ultimately return
Dim Books() As Book

'we're going to use an array list to store the initial collection
'of book items
Dim AL As New ArrayList

'and we'll need a stream reader in order to read the file
Dim sr As StreamReader
Dim Entry As String


'first, let's open the file
sr = New StreamReader(File.OpenRead(FilePath))


'next, read in each line of data from the file and create
'a book object for it
Do
Entry = sr.ReadLine

'convert this line of data into a book object
If Not Entry Is Nothing Then

'since this is a column delimited line, split it apart
Dim arr() As String = Split(Entry, ",")

'define a new book object and populate its values
Dim B As New Book
B.Title = arr(0)
B.Author = arr(1)
B.ISBN = arr(2)

'now, add it to the array list
AL.Add(B)
End If


'keep going until we reach the end of the file
Loop Until Entry = Nothing


'create an array of book objects of the correct size
'and populate it from the array list
Redim Books(AL.Count - 1)
For ndx As Integer = 0 To AL.Count - 1

'since the array list only stores Object types, we'll need to
'cast the object as a book type
Books(ndx) = CType(AL.Item(ndx), Book)
Next

'and return the array
Return Books
End Function



'-------------------------------------------
'Here's a quick test of this function
'-------------------------------------------
Public Sub Main

'here is the target array we'll be using
Dim mBooks() As Book

'read in the contents of "books.csv" found in the same directory
'as this application
mBooks = GetBooks("books.csv")

'print out the results of this operation
For Ndx As Integer = 0 To UBound(mBooks)
Dim B As Book = mBooks(ndx)
Console.WriteLine(B.Title & ": " & B.Author & " : " & B.ISBN)
Next

End Sub



HTH


Ralf
 
C

Cor Ligthert [MVP]

Me,

If you use a dataset\table to read\write as XML instead of CSV than your
problem becomes very simple. (while you have than as well not the trouble
that a CSV file is culture depended).

To get your xml file

myDataSet.ReadXML(path)

To write your xml file

myDataset.WriteXML(path) 'however secure this so that you are sure that you
don't overwrite it direct but delete the old original as that is done.

To create it
dim myDataset as new Dataset
dim myDataTable as new DataTable
myDataset.Tables.Add(myDataTable)
myDatatable.columns.add("Book")
myDatatable.columns.add("Author")
myDatatable.columns.add("ISBN")

To load a new a row (with hundred other methods)
myDataTable.Loadrow(New object() {"MyBook","TheAuthor","ISBN"},true)

A dataset is a very sophisticated class inside ADONET, therefore look for
how to handle it to DataTable and DataRow on MSDN, or ask here or in the
ADONET newsgroup if you have a problem after investigating it.

I hope this gives some idea's.

Cor
 
M

me

Hey thanks a million guys - that is really helpful - appreciate it.

Will be going ahead with your suggestions and report back!

Cheers
 
M

me

Cor Ligthert said:
Me,

If you use a dataset\table to read\write as XML instead of CSV than your
problem becomes very simple. (while you have than as well not the trouble
that a CSV file is culture depended).

To get your xml file

myDataSet.ReadXML(path)

To write your xml file

myDataset.WriteXML(path) 'however secure this so that you are sure that
you don't overwrite it direct but delete the old original as that is done.

To create it
dim myDataset as new Dataset
dim myDataTable as new DataTable
myDataset.Tables.Add(myDataTable)
myDatatable.columns.add("Book")
myDatatable.columns.add("Author")
myDatatable.columns.add("ISBN")

To load a new a row (with hundred other methods)
myDataTable.Loadrow(New object() {"MyBook","TheAuthor","ISBN"},true)

A dataset is a very sophisticated class inside ADONET, therefore look for
how to handle it to DataTable and DataRow on MSDN, or ask here or in the
ADONET newsgroup if you have a problem after investigating it.

I hope this gives some idea's.

Cor


Thanks Cor,

This makes me wonder - is there a generic command or function that will
write out/read in the contents of a Collection or Arrayset to an XML file?
 
M

me

Armin Zingler said:
If your array's name is 'Books', you can store the reference to a new book
directly in this array:

Books(Index) = New Book.Book

Now the item at position Index points to the book that has been created in
the same line.

'Index' is a variable that you will have to manage. It should point to the
first empty position within the array. At the beginning, the value of
Index
is 0. After you stored a reference to a new book at the position that
Index
points to, Index has to be incremented by 1, so next time you will store a
new book at the next position in the array. There are alternatives better
than arrays that I'll mention below.

After this, you can set the book's properties:

Books(Index).Title = ...
Books(index).author = ...

Or, if you have many properties:

With Books(Index)
.Title = ...
.author = ...
End With




Using arrays and classes is not a contradiction. BTW, an array is class,
too.

To loop through all books in the array:

For i as integer = 0 to index - 1
Debug.writeline(books(i).title)
Debug.writeline(books(i).author)
next i

You see how to access the books in the array and how to access the
properties. You can access them the same way if you write them to a file.
I
don't know how you do it, thus I use debug.writline here.

There are alternatives:

For i as integer = 0 to index - 1
dim LoopBook as book
LoopBook = books(i)
Debug.writeline(LoopBook.title)
Debug.writeline(LoopBook.author)
next i

or

For i as integer = 0 to index - 1
with books(i)
Debug.writeline(.title)
Debug.writeline(.author)
end with
next i


Now we come to how to read the books from the file. I don't know how
exactly
you intend to read the file, thus I focus on creating the objects and
storing them in the array:


index = 0

do until end-of-file
dim Author, Title as string
'read one line and store the values in 'Author' and 'Title'
'...

books(index) = new book
books(index).title = title
books(index).author = author
index += 1
loop


As you see, using an array can be much work:

- You can not change the size of an array. If you need more/less items,
you
have to create a new array and copy the content of the old array into the
new one (ReDim Preserve).

- If you define your array being able to hold 100 items maximum, you need
an
additional variable, called 'Index' in this example, that tracks the
number
of items that are used within the array.

- You can not delete items from the array. You would have to copy items to
avoid having an unused item in the array. An unused item is 'Nothing',
i.e.
it does not point to a book.

- If, within the array, unused items are allowed, you would have to loop
through all the items if you want to find an unused item where you can
store
the reference to a new book.


Therefore, you'd better use another sort of collection. An arraylist is
often used. See the namespace System.Collections for more information.
With
an arraylist, you can add and remove items without caring about the space
for new/removed items.

dim books as new arraylist

To add a new book - also when reading the file:

dim b as book

b = new book
b.title = ...
b.author = ...

books.add(b) 'add the book to the arraylist

Use books.RemoveAt (or books.remove) to remove a book from the arraylist.
Use the arraylist's count property to get the number of items in the list.
As an arraylist can contain references to any type of object, the type of
the arraylist's 'Item' property is 'Object'. For this reason, you have to
use type casting:

dim b as book

b = directcast(books(17), book)
debug.writline(b.title)
debug.writline(b.author)



See also:
http://msdn.microsoft.com/library/en-us/vbcn7/html/vaconManagingGroupsOfObjects.asp

http://msdn.microsoft.com/library/en-us/cpguide/html/cpcongroupingdataincollections.asp

http://msdn.microsoft.com/library/en-us/vbcon/html/vbconComponentsThatContainOtherComponents.asp
(especially: "Walkthrough: Creating Your Own Collection Class")


(As I see now, the links contain already all you need. :)


Armin


Thanks for the feedback Armin,

So is an arraylist like a collection? Only, not for classes, just for
variables with types?
 
A

Armin Zingler

me said:
Thanks for the feedback Armin,

So is an arraylist like a collection?

I think the links provided explain each type of collection in detail. :) I
can not explain the differences better.
Only, not for classes, just for variables with types?

I do not know what you mean with "variables with types". Every variable has
a type. You can store every object in an Arraylist.

A "collection" is both, a general term for Array, Arraylist, Hashtable and
all other classes in the System.Collections namespace, as well as the name
of a class in the Microsoft.VisualBasic namespace. It depends on your needs
what type of collection you should use.


Armin
 
C

Cor Ligthert [MVP]

This makes me wonder - is there a generic command or function that will
write out/read in the contents of a Collection or Arrayset to an XML file?
Why, the DataSet is for much data needs a better collection than an
ArraySet.

An analogy

Use a car if you need that, use a bicycle as you need that. By instance in
the city where I am born, you can better go by bicycle than by car, but you
should not use that to go out of that city. There are bicycles that you can
fold. They ride bad, and it is forever a lot of work to fold and to unfold
them.

Cor
 
P

Phill W.

You need a Class ("Book") to hold information about each individual Book.

You need /another/ Class that will hold your "list" of Books.
To start with, an ArrayList would probably do.
I have set up a class (called Book) with properties such as Title, Author,
ISBN and can get/set them

Good. Now add a Constructor (Sub New) so that you can create
a Book with all those properties filled in in one go, as in

Public Sub New( _
ByVal Title as String _
, ByVal Author as String _
, ISBN as String? _
)
' Store each argument into the equivalent property.
End Sub

Then, as you create ach book, add it to the Arraylist, as in

Dim ABook as Book
Dim AllBooks as New ArrayList

ABook = New Book( "Title", "Author", "ISBN" )
AllBooks.Add( ABook )
So how does one then cycle through these items when saving?

For Each eBook as Book _
In AllBooks
' Save Book information to File
Next
How do we create all the instances when first loading the CSV file?

Dim sr as New StreamReader( "file" )
Dim sRecord as String _
= sr.ReadLine

Do While Not ( sLine Is Nothing )
' Extract Title, Author and ISBN

' Create Book object
Dim ABook as New Book( Title, Author, ISBN )

' Add to list of books
AllBooks.Add( ABook )

' Get the next one
sRecord = sr.ReadLine
Loop
sr.Close()

Now, using the ArrayList is only start - there's no easy way to, say,
pull out a given book by Title - you'd have to loop through each Book
in the ArrayList, but there are other Collection classes (e.g. Dictionary)
that you could use instead of ArrayList.

HTH,
Phill W.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top