Newbie VB question

  • Thread starter Thread starter Ot
  • Start date Start date
O

Ot

I am an experienced programmer, but new to VB.NET. If you don't mind
answering a really fundamental question, it would be appreciated.

I am writing an application in which I want to have a "list" in the program
sort of like this (psuedocode)

ItemList
...NumberOfItems
...Item (number of occurrences is NumberOfItems)
.....ItemID
.....ItemAttribute1
.....ItemAttribute2
.....ItemAttribute3
...end Item
End ItemList

I want the ability to write a function that is handed the ItemID and
returns a structure that is the right occurrence of the Item. It is not
critical whether it returns a new distinct occurrence of Item, or a pointer
to the Item in the ItemList.

Also a subroutine to add to the list (but only if it isn't already there).

It feels like I am writing an "object" -- that is a class? -- that exposes
the two "methods" Add and Find. Unsure if this is actually the case. The
ItemList and data would appropriately be private to the object. I would
expect the user to be able to instantiate an instance of my "object" and
then use the subroutine and function to manipulate it.

I suppose I want a separate Type called Item. (Exactly best way to declare
so it can be used globally?) It doesn't feel VBish to declare this
globally, but nevertheless, I want the caller to be able to make use of the
description provided for an individual item. The caller needs to be able
to access all the fields.

Then I might have a separate variable called NumberOfItems which would
indicate how many. But this doesn't seem VBish. I suspect that when I
declare an array I might get a freebie. An attribute of the array that is
the count of the number of contents. I haven't seen exactly how to do that
however. I was hoping that something like ItemList.Count might
automatically be there for use locally.

My guess is that my subroutine/function would somehow use a "For each Item
in ItemList" or somesuch and then have a simple if/then in the loop to find
the right Item by matching ItemID. I can see how a simple for/next works,
but not really how a "for each" might work.

For i = 1 to NumberOfItems
If ItemToFind = ItemID(i)
Return Item(i)
endif
next i

On the other hand, perhaps there is a built-in linear search function that
I don't know about.

My frustration is the I could write this in COBOL (with a limitation on the
largest number in ItemList), FORTRAN (same limitation), IBM360 assembler
language (no limitation), as well as a number of others from FoxBase to
SAS. I am not thinking in VB yet, I need a little guidance.

TIA!
 
Hi,

Take a look at the hashtable class - it should give you exactly what you're
looking for: key value pairs, enabling access to the value through the key.
Your can iterate the hashtable using an object called 'dictionaryentry':
dim d as dictionaryentry
for each d in ht ' ht is the hashtable

HTH,

Bernie Yaeger
 
I tried this:

Public Class ItemList

Public Structure Item
Dim ItemID As Int32
Dim Attribute1 As Boolean
Dim Attribute2 As Boolean
Dim Attribute3 As Boolean
End Structure
Private ItemArray() As Item

Public Sub Add(ByVal ItemIDtoAdd As Int32, ByVal attr1ok As Boolean,
ByVal attr2ok As Boolean, ByVal attr3ok As Boolean)
If Find(ItemIDtoAdd) = Nothing Then ' SYNTAX
ERROR HERE
Dim i = ItemArray.GetUpperBound(1) + 1
ReDim Preserve ItemArray(i)
ItemArray(i).ItemID = ItemIDtoAdd
ItemArray(i).Attribute1 = attr1ok
ItemArray(i).Attribute2 = attr2ok
ItemArray(i).Attribute3 = attr3ok
End If
End Sub

Public Function Find(ByVal ItemIDtoFind As Int32) As Item
Dim i = ItemArray.GetUpperBound(1)
Dim j As Integer
For j = 1 To i
If ItemIDtoFind = ItemArray(j).ItemID Then
Return ItemArray(j)
End If
Next
Return Nothing
End Function

End Class

The IDE complains that the = operator isn't defined for this type: Item.
When I change it to "is Nothing" it complains that Item is a value type not
a reference type. Yours in confusion....
 
Hi,

Don't know what to suggest. Try calling the find function with a variable
of type item. Then use 'if itemvar = nothing etc

By the way, item is probably a poor choice; it may well be a reserved word
under certain circumstances.

HTH,

Bernie
 
When I do that it complains that it [Find(ItemIDtoAdd)] is a value type not
a reference type. (I hate being a newbie, but this "explanation" by the
compiler is lost on me.)
 
Thanks, Bernie, I looked into hashtable class and, yes, that is just the
right kind of VB thinking I needed.

I am still confused as to why the little class I wrote has the problems it
has, though. Can you shed any light there?
 
Hi,

There's a subtle difference between value types and reference types. As you
may guess, reference types are pointers that point to values stored in
memory in an area called the managed heap. Value types do not point to
values but rather are the values themselves just like the difference between
a variable passed by ref or by val). This I have gotten from several books,
notably Balena, Programming MS Visual Basic .Net. He explains further but
did not enlighten me as to why your error is occurring, sorry to say.

Don't know what to recommend; sorry. You might want to post more directly
to Herfried Wagner; he monitors this ng and he knows, I think, everything;
nice guy too.

HTH,

Bernie
 
My fault, I didn't see that you where returning a structure and not a class.
Therefore, IS Nothing won't work as you found out.

Try this out to see if it works:

Change this line----> If Find(ItemIDtoAdd) = Nothing ---- to this ----->If
Find(ItemIDtoAdd).ItemID = 0

Public Sub Add(ByVal ItemIDtoAdd As Int32, ByVal attr1ok As Boolean,ByVal
attr2ok As Boolean, ByVal attr3ok As Boolean)

If Find(ItemIDtoAdd).ItemID = 0 Then ' SYNTAX

Dim i = ItemArray.GetUpperBound(1) + 1
ReDim Preserve ItemArray(i)
ItemArray(i).ItemID = ItemIDtoAdd
ItemArray(i).Attribute1 = attr1ok
ItemArray(i).Attribute2 = attr2ok
ItemArray(i).Attribute3 = attr3ok
End If
End Sub


Ot said:
When I do that it complains that it [Find(ItemIDtoAdd)] is a value type not
a reference type. (I hate being a newbie, but this "explanation" by the
compiler is lost on me.)

Brian said:
Use the IS keyword instead of the =

Example:

If Find(ItemIDtoAdd) IS Nothing Then
 
Hi,

When you define a structure like this, the compiler doesn't know how to
compare two instances of the structure to see if they are equal (like it can
with primitives like integers etc.)

What you need to do is define an "Equals" method in your structure and use
this to compare for equality. For example:

---------------------

Public Structure Item
Public ItemID As Int32
Public Attribute1 As Boolean
Public Attribute2 As Boolean
Public Attribute3 As Boolean

' Comparison Function
Public Overloads Function Equals(ByVal CompareTo as Item) as Boolean

return (Me.ItemID = ComapareTo.ItemID) andalso _
(Me.Attribute1 = CompareTo.Attribute1) andalso _
(Me.Attribute2 = CompareTo.Attribute1) andalso _
(Me.Attribute3 = CompareTo.Attribute1)


End Function


End Structure

--------------------

You wound then call this method to test to see if two instances of the
structure are equal.

If you want to get into more complex (and more useful) ways of doing this,
have a look a the "IComparable" interface. You can implement this in your
class or structure to allow sorting and comparing of arrays of objects.

To quickly explain the difference between a value type and a reference type:
A value type consists of one thing - the value (which can be an integer or
number of integers and strings in a structure etc.). A reference type
consists of two things - the value and a sort of pointer that points to the
value in memory. When you assign a value type variable to another value type
variable, the value is *copied* to the new memory location. When you assign
a reference variable to another reference variable, the pointer is copied -
not the actual value.

As a structure is a "value type", you cannot use the "Is" operator on it.
The "Is" operator should only be used to comapre object references to see if
they point to the same object.

The next version of VB will allow you to overload operators like "=" so you
can define your own methods to compare and do other operations such as
addition on.

Hope this helps,

Trev.
 
Trev,

Thanks for the clear explanation. But, of course, any answer raises
further questions.

Let me draw some conclusions and ask for verification. Let's see....

1. If I use "Is" to compare to objects, the pointers themselves are
compared so that "A is B" if and only if the pointers are to the exact same
object. If I want to see if the contents of the two objects are equal, not
necessarily the same object, I would have to write in the class that
defines/makes the type of objects A and B a routine that overloads the
equal operator?

2. My guess is that when I declare a class I get "free" a default
constructor. I would suppose I write a procedure "New" to give my object
default values. But I am unclear as to what the defaults are if I don't
write a "New".

3. In this particular case, there is this "structure" defined in the
class. This "type" is accessible by other programs that include the class.
The caller can specify "New Item". I am unclear as to how that new Item is
initialized. Can/should I write a Sub New defined in the definition of the
structure? Similar to what you gave me for Equals?

4. As a matter of VB style. Would it have been better to define Item as a
Class with 4 attributes rather than as a structure? I did the structure
thing because that is the way I visualized this Item -- as one thing with
parts which, to me, seems like a structure.

Thanks in advance...
 
1. If I use "Is" to compare to objects, the pointers
themselves are compared so that "A is B" if and only
if the pointers are to the exact same object.
If I want to see if the contents of the two objects
are equal, not necessarily the same object, I
would have to write in the class that defines/makes
the type of objects A and B a routine that overloads
the equal operator?

Yes. Except that "Equals" is a function, not an operator. In the next
version of VB you'll be able to overload the "=" operator. To call the
"equals" function, use "If objA.Equals(objB) then..."

2. My guess is that when I declare a class I get
"free" a default constructor. I would suppose
I write a procedure "New" to give my object
default values. But I am unclear as to what
the defaults are if I don't write a "New".

If you don't initialize variables yourself, then they will automatically be
set to their defaults. In VB these are 0 for numeric types
(int,byte,single,double etc.). Objects will be set to Nothing (including
Strings).

There are two ways of initializing member variables - in their decleration
or in a constructor e.g.

-----------

' Initialize in decleration
Private mName as String = "Hello"


' Initialize in Constructor
Public Sub New()

' Call base constructor
MyBase.New

' Initialize member variables
Me.mName = "Hello From Constructor"

End Sub

--------

Don't do both ways at the same time for the same variable - there isn't any
point.

3. In this particular case, there is this
"structure" defined in the class. This
"type" is accessible by other programs that
include the class. The caller can specify
"New Item". I am unclear as to how that new
Item is initialized. Can/should I write a
Sub New defined in the definition of the
structure? Similar to what you gave me for Equals?

You cannot define a "default" Sub New for a structure that doesn't take any
parameters, but you can declare one that takes parameters. If you want to
initialize variables to something other than their defualts in a structure,
initialize them as part of their decleration instead of in a sub new as
shown above.
4. As a matter of VB style. Would it have
been better to define Item as a
Class with 4 attributes rather than as a
structure? I did the structure
thing because that is the way I visualized
this Item -- as one thing with
parts which, to me, seems like a structure.

Don't base your decision on when to use a structure instead of a class on
what it looks like. For performance, keep structures small. If you need a
parameter-less constructor, or need to use inheritance use a class. Have a
look at

http://msdn.microsoft.com/library/d...-us/dv_vstechart/html/vbtchuseclassstruct.asp

for a better explanation between a structure and a class.

Hope this helps,

Trev.
 
Back
Top