structure types and help

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello group,

I am trying to get used to vb.net coming from a far far far away set of tools.

What i want to do is setup an object in my application that contains other
object types, that act like collections.

For example:

objQuotes.Quotes("2004-10-08").Item("MSFT").StockQuote = "45.45"

The structure really needs to be laid out like this:

StockData holds a Quotes collection for each day - the day would be the key.
The quotes object would have an object for each stock i'd like to record
data for.. each stock needs to record several properties, like the
symbol/ticker, an internal ID, the value, and the market valuation.

I just can't seem to get to where I want to be with collections:

The code I am trying looks like:

Public Structure typeStocks
Dim Items As Collection
End Structure

Public Structure typeStocksData
Dim Items As Collection
End Structure

Public Structure typeQuote
Dim StockID As Integer
Dim Quote As Decimal
Dim MarketCap As Long
End Structure

But the problem is that to get data out I have to create a bunch of objects
like:

objQuotes = objStockData.Items("2004-10-08")
objQuote = objQuotes.Item("MSFT")
MsgBox(objQuote.StockQuote)

Can anyone help me get this figured out?? I am just not following how to
get to where I want from where I am!

Many thanks!
 
Dan,
I would recommend using Classes. Classes are reference types, Structures are
value types. In your scenario value types will probably cause anti-aliasing
problems you do not want. (a copy of the Stock (typeQuote) would be
returned.

Something like:

Public Shared Sub Main()
Dim objQuotes As New QuoteCollection
objQuotes.Add(#10/8/2004#).Add("MSFT")
objQuotes.Quotes(#10/8/2004#).Item("MSFT").Quote = 45.45D
End Sub

Public Class QuoteCollection
Inherits DictionaryBase

' uses DateTime.Date so only date is the key, not date & time

Public Function Add(ByVal key As DateTime) As StockCollection
Dim value As New StockCollection
Me.InnerHashtable.Add(key.Date, value)
Return value
End Function

Default Public ReadOnly Property Quotes(ByVal key As DateTime) As
StockCollection
Get
Return DirectCast(Me.InnerHashtable(key.Date), StockCollection)
End Get
End Property

End Class

Public Class StockCollection
Inherits DictionaryBase

Public Function Add(ByVal key As String) As Stock
Dim value As New Stock
Me.InnerHashtable.Add(key, value)
Return value
End Function

Default Public ReadOnly Property Item(ByVal key As String) As Stock
Get
Return DirectCast(Me.InnerHashtable(key), Stock)
End Get
End Property

End Class

Public Class Stock
Public ID As Integer
Public Quote As Decimal
Public MarketCap As Long
End Class

QuoteCollection (your typeStocks) is a strongly typed collection of
StockCollections by Date.

StockCollection (your typeStocksData) is a strongly typed collection of
Stocks by Name (String).

Both QuoteCollection & StockCollection inherit from
System.Collections.DictionaryBase allowing strongly typed collections of a
specific value by a key. There is also a System.Collections.CollectionBase
that allows a strongly typed collection of values by an index. There is a
System.Collections.Specialized.NameObjectCollectionBase that you can use if
you want a strongly typed collection by both key & index.

The Add methods above only allow you to add a specific type, In the case
above the Add method takes the key & returns a new value. I could just as
easily added key, value pairs.

Public Sub Add(ByVal key As String, ByVal value As Stock)
Me.InnerHashtable.Add(key, value)
End Sub

Or if a Stock knew its Key.

Public Sub Add(ByVal value As Stock)
Me.InnerHashtable.Add(value.Key, value)
End Sub

Public Class Stock

Public Readonly Key As String

Public Sub New(ByVal key As String)
Me.Key = key
End Sub

...

End Class

The "Default" properties allow you to use the property name or not, both of
the following lines are valid:

objQuotes.Quotes(#10/8/2004#).Item("MSFT").Quote = 45.45D

objQuotes(#10/8/2004#)("MSFT").Quote = 45.45D

Although in this case I find the first may be more readable.

Robin A. Reynolds-Haertle's book "OOP with Microsoft Visual Basic .NET and
Microsoft Visual C# .NET - Step by Step" from Microsoft Press covers the how
of OOP, to create object models such as this.

Hope this helps
Jay
 
Dan,
I threw together an example for you, I don't know if my way is the
correct way, or the right way, or a valid way, but, it seems to work. I
didn't put a lot of thought into it so it will probably contain bugs. If
you're lucky others will give you ideas on how to improve/correct this. I
hope this helps,

Jared


'I created a new form, and placed a single button on it.

'<formCode>
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
test()
End Sub

Sub test()
Dim objQuotes As New MyQuotes
objQuotes.Quotes("2004-10-08").Item("MSFT").StockID = "45.45"
MsgBox(objQuotes.Quotes("2004-10-08").Item("MSFT").StockID)
Dim q As New Quote
With q
.StockID = 11
.Quote = 45.87
.MarketCap = 100
End With
objQuotes.Quotes("2004-10-08").Item("MSFT") = q
Dim newquote As Quote = objQuotes.Quotes("2004-10-08").Item("MSFT")
Dim RetVal As String = "Market Cap: " & newquote.MarketCap &
ControlChars.CrLf
RetVal += "Stock ID: " & newquote.StockID & ControlChars.CrLf
RetVal += "Quote: " & newquote.Quote
MessageBox.Show(RetVal)
End Sub

'</formCode>


' I created three classes to hold the data
Public Class MyQuotes
Dim _mQuotes As Collection = New Collection
' Returns a collection of quotes by date
Public Overloads Property Quotes(ByVal Index As String) As Quotes
Get
Try
Convert.ToDateTime(Index)
Catch icex As InvalidCastException
MessageBox.Show("Index supplied was not in a valid format.")
Exit Property
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Property
End Try
' Valid format
If _mQuotes.Count > 0 Then
' See if the item exists
' if the item exists it will return the item in the return
statement
If _mQuotes.Item(Index) Is Nothing Then
' Doesn't exist, add it
_mQuotes.Add(New Quotes, Index)
End If
Else
' Item doesn't exist - add it
_mQuotes.Add(New Quotes, Index)
End If
' Return the item to the caller
Return _mQuotes(Index)
End Get
Set(ByVal Value As Quotes)
Try
Convert.ToDateTime(Index)
Catch icex As InvalidCastException
MessageBox.Show("Index supplied was not in a valid format.")
Exit Property
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Property
End Try
' Valid format
If _mQuotes.Count > 0 Then
' See if the item exists
' if the item exists it will return the item in the return
statement
If _mQuotes.Item(Index) Is Nothing Then
' Doesn't exist, add it
_mQuotes.Add(Value, Index)
End If
Else
' Item doesn't exist - add it
_mQuotes.Add(Value, Index)
End If
End Set
End Property
End Class
Public Class Quotes
Dim _mQuote As Collection = New Collection
' Returns a quote item by stock symbol
Public Property Item(ByVal StockSymbol As String) As Quote
Get
' Check to see if the collection is empty
If _mQuote.Count > 0 Then
If _mQuote.Item(StockSymbol) Is Nothing Then
_mQuote.Add(New Quote, StockSymbol)
End If
Else
_mQuote.Add(New Quote, StockSymbol)
End If
Return _mQuote(StockSymbol)
End Get
Set(ByVal Value As Quote)
If _mQuote.Item(StockSymbol) Is Nothing Then
_mQuote.Add(Value, StockSymbol)
Else
Dim q As Quote = CType(_mQuote.Item(StockSymbol), Quote)
q.StockID = Value.StockID
q.Quote = Value.Quote
q.MarketCap = Value.MarketCap
End If
End Set
End Property
End Class
Public Class Quote
' Field variables
Private _mStockID As Integer
Private _mQuote As Decimal
Private _mMarketCap As Long
' Accessors
Public Property StockID() As Integer
Get
Return _mStockID
End Get
Set(ByVal Value As Integer)
_mStockID = Value
End Set
End Property
Public Property Quote() As Decimal
Get
Return _mQuote
End Get
Set(ByVal Value As Decimal)
_mQuote = Value
End Set
End Property
Public Property MarketCap() As Long
Get
Return _mMarketCap
End Get
Set(ByVal Value As Long)
_mMarketCap = Value
End Set
End Property
End Class
 
Jay,
I actually have the book you referenced, but, as you can tell I didn't
read it. It's on my TODO list now, I guess this is why you're the MVP and
I'm just a system administrator ;-)
Jared
 

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

Back
Top