By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 974 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 IT Pros & Developers. It's quick & easy.

Creating a strongly-typed enumerable collection?

P: n/a
I'd like to create a strongly-typed collection of objects that are indexed
by a string value (key is a string). I'd also like to allow users to iterate
over the collection using a For-each loop where an object of the contained
type is returned (instead of just the standard DictionaryEntry object).

- only allow objects of type MyObj to be added to the collection
- return a MyObj type in the For-each loop

What's the best way to do this?

I tried to have my collection class inherit from DictionaryBase but I had
trouble getting it to return MyObj objects in the For-each. By default its
retruning DictionaryEntry objects and it wouldn't let me override the
inherited GetEnumerator() function.

I also looked at inheriting from CollectionBase but this takes an integer
for the key values.

Is creating a class that implements IEnumerable and contains a private
collection object the way to go here?

Thanks in advance for the help/advice.

Michael
Nov 20 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
I ran into a similar problem the way that i solved it was to have a class
that inherited from CollectionBase. This class also contained a SortedList.
Anytime i added something to the list object of the collectionBase i added
it to the sorted list. By doing this i was able to access my items by key or
by index.

Shawn

"Michael K. Walter" <mk******@sqlcraft.com> wrote in message
news:eQ**************@tk2msftngp13.phx.gbl...
I'd like to create a strongly-typed collection of objects that are indexed
by a string value (key is a string). I'd also like to allow users to iterate over the collection using a For-each loop where an object of the contained
type is returned (instead of just the standard DictionaryEntry object).

- only allow objects of type MyObj to be added to the collection
- return a MyObj type in the For-each loop

What's the best way to do this?

I tried to have my collection class inherit from DictionaryBase but I had
trouble getting it to return MyObj objects in the For-each. By default its
retruning DictionaryEntry objects and it wouldn't let me override the
inherited GetEnumerator() function.

I also looked at inheriting from CollectionBase but this takes an integer
for the key values.

Is creating a class that implements IEnumerable and contains a private
collection object the way to go here?

Thanks in advance for the help/advice.

Michael

Nov 20 '05 #2

P: n/a
Thanks for the note Shawn.

I've tried a number of options (including your suggestion) and, while I can
set this up using various collection types as my base, I still end up in
situation where I have to have the end users of my collection cast to the
appropriate type inside of the For-each loop. So far, I've had it return
either a DictionaryEntry or generic Object type in the For-Each that I had
to manipulate/cast to MyObj type before using the retrieved object. I was
trying to avoid this but I'm beginning to think that this cannot be done in
..Net (like I can in VB6).

Example:

Dim d1 as New Dog("Duncan","Golden Retriever")
Dim d2 as New Dog("Louie", "Lab")
Dim d3 as New Dog("Butch","Beagle")

Dim Kennel as New DogCollection

Kennel.Add(d1)
Kennel.Add(d2)
Kennel.Add(d3)

Dim o as Object
Dim d as Dog

For Each o In Kennel
d = CType(o, Dog)
Console.Write(d.Name)
Next

But I'm trying to get the last lines to look like this (no Object variable
declaration or Cast required):

Dim D as Dog

For Each d in Kennel
Console.Write(d.Name)
Next

Even using IEnumerable/IEnumerator didn't help since the IEnumerator
Current() property returns a generic Object type (and I couldn't get it
compile when I changed the return type to Dog).

Am I missing something?

Michael

"Shawn Hogan" <NOSPAM> wrote in message
news:eB**************@TK2MSFTNGP12.phx.gbl...
I ran into a similar problem the way that i solved it was to have a class
that inherited from CollectionBase. This class also contained a SortedList. Anytime i added something to the list object of the collectionBase i added
it to the sorted list. By doing this i was able to access my items by key or by index.

Shawn

"Michael K. Walter" <mk******@sqlcraft.com> wrote in message
news:eQ**************@tk2msftngp13.phx.gbl...
I'd like to create a strongly-typed collection of objects that are indexed by a string value (key is a string). I'd also like to allow users to

iterate
over the collection using a For-each loop where an object of the contained type is returned (instead of just the standard DictionaryEntry object).

- only allow objects of type MyObj to be added to the collection
- return a MyObj type in the For-each loop

What's the best way to do this?

I tried to have my collection class inherit from DictionaryBase but I had trouble getting it to return MyObj objects in the For-each. By default its retruning DictionaryEntry objects and it wouldn't let me override the
inherited GetEnumerator() function.

I also looked at inheriting from CollectionBase but this takes an integer for the key values.

Is creating a class that implements IEnumerable and contains a private
collection object the way to go here?

Thanks in advance for the help/advice.

Michael


Nov 20 '05 #3

P: n/a
This class seems to do what you want when i run it with your desired code. I
ran with option strict on and it didn't need any ctype's in the client code.
Hope this helps...
Public Class DogCollection
Inherits CollectionBase
Private _keyCollection As New Collections.SortedList
Default Public Property Item(ByVal index As Integer) As dog
Get
Return CType(List.Item(index), dog)
End Get
Set(ByVal Value As dog)
Dim item As dog = CType(List.Item(index), dog)
Dim itemKey As String =
DirectCast(_keyCollection.GetKey(_keyCollection.In dexOfValue(item)), String)
_keyCollection.Item(itemKey) = Value
List.Item(index) = Value
End Set
End Property
Default Public Property Item(ByVal key As String) As dog
Get
Return CType(_keyCollection.Item(key), dog)
End Get
Set(ByVal Value As dog)
Dim item As dog = CType(_keyCollection.Item(key), dog)
Dim itemIndex As Integer = list.IndexOf(item)
list.Item(itemIndex) = Value
_keyCollection.Item(key) = Value
End Set
End Property
Public Sub Add(ByVal key As String, ByVal newItem As dog)
list.Add(newItem)
_keyCollection.Add(key, newItem)
End Sub
Public Sub Remove(ByVal key As String)
Dim item As dog = CType(_keyCollection.Item(key), dog)
list.Remove(item)
End Sub
Protected Overrides Sub OnClearComplete()
_keyCollection.Clear()
End Sub
Protected Overrides Sub OnRemoveComplete(ByVal index As Integer, ByVal value
As Object)
_keyCollection.Remove(_keyCollection.GetKey(_keyCo llection.IndexOfValue(valu
e)))
End Sub
End Class
Shawn

"Michael K. Walter" <mk******@sqlcraft.com> wrote in message
news:e3**************@TK2MSFTNGP12.phx.gbl...
Thanks for the note Shawn.

I've tried a number of options (including your suggestion) and, while I can set this up using various collection types as my base, I still end up in
situation where I have to have the end users of my collection cast to the
appropriate type inside of the For-each loop. So far, I've had it return
either a DictionaryEntry or generic Object type in the For-Each that I had
to manipulate/cast to MyObj type before using the retrieved object. I was
trying to avoid this but I'm beginning to think that this cannot be done in .Net (like I can in VB6).

Example:

Dim d1 as New Dog("Duncan","Golden Retriever")
Dim d2 as New Dog("Louie", "Lab")
Dim d3 as New Dog("Butch","Beagle")

Dim Kennel as New DogCollection

Kennel.Add(d1)
Kennel.Add(d2)
Kennel.Add(d3)

Dim o as Object
Dim d as Dog

For Each o In Kennel
d = CType(o, Dog)
Console.Write(d.Name)
Next

But I'm trying to get the last lines to look like this (no Object variable
declaration or Cast required):

Dim D as Dog

For Each d in Kennel
Console.Write(d.Name)
Next

Even using IEnumerable/IEnumerator didn't help since the IEnumerator
Current() property returns a generic Object type (and I couldn't get it
compile when I changed the return type to Dog).

Am I missing something?

Michael

"Shawn Hogan" <NOSPAM> wrote in message
news:eB**************@TK2MSFTNGP12.phx.gbl...
I ran into a similar problem the way that i solved it was to have a class
that inherited from CollectionBase. This class also contained a SortedList.
Anytime i added something to the list object of the collectionBase i added it to the sorted list. By doing this i was able to access my items by

key or
by index.

Shawn

"Michael K. Walter" <mk******@sqlcraft.com> wrote in message
news:eQ**************@tk2msftngp13.phx.gbl...
I'd like to create a strongly-typed collection of objects that are

indexed by a string value (key is a string). I'd also like to allow users to

iterate
over the collection using a For-each loop where an object of the contained type is returned (instead of just the standard DictionaryEntry object).
- only allow objects of type MyObj to be added to the collection
- return a MyObj type in the For-each loop

What's the best way to do this?

I tried to have my collection class inherit from DictionaryBase but I had trouble getting it to return MyObj objects in the For-each. By default its retruning DictionaryEntry objects and it wouldn't let me override the
inherited GetEnumerator() function.

I also looked at inheriting from CollectionBase but this takes an integer for the key values.

Is creating a class that implements IEnumerable and contains a private
collection object the way to go here?

Thanks in advance for the help/advice.

Michael



Nov 20 '05 #4

P: n/a
Shawn,

I created a console app/test harness for this and it works fine...thank you.

Now I have to go back to my actual app, conpare and see where I went wrong
(I'm not really dealing with dogs and kennels - as you may have already
guessed).

Thanks again!

"Shawn Hogan" <NOSPAM> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
This class seems to do what you want when i run it with your desired code. I ran with option strict on and it didn't need any ctype's in the client code. Hope this helps...
Public Class DogCollection
Inherits CollectionBase
Private _keyCollection As New Collections.SortedList
Default Public Property Item(ByVal index As Integer) As dog
Get
Return CType(List.Item(index), dog)
End Get
Set(ByVal Value As dog)
Dim item As dog = CType(List.Item(index), dog)
Dim itemKey As String =
DirectCast(_keyCollection.GetKey(_keyCollection.In dexOfValue(item)), String) _keyCollection.Item(itemKey) = Value
List.Item(index) = Value
End Set
End Property
Default Public Property Item(ByVal key As String) As dog
Get
Return CType(_keyCollection.Item(key), dog)
End Get
Set(ByVal Value As dog)
Dim item As dog = CType(_keyCollection.Item(key), dog)
Dim itemIndex As Integer = list.IndexOf(item)
list.Item(itemIndex) = Value
_keyCollection.Item(key) = Value
End Set
End Property
Public Sub Add(ByVal key As String, ByVal newItem As dog)
list.Add(newItem)
_keyCollection.Add(key, newItem)
End Sub
Public Sub Remove(ByVal key As String)
Dim item As dog = CType(_keyCollection.Item(key), dog)
list.Remove(item)
End Sub
Protected Overrides Sub OnClearComplete()
_keyCollection.Clear()
End Sub
Protected Overrides Sub OnRemoveComplete(ByVal index As Integer, ByVal value As Object)
_keyCollection.Remove(_keyCollection.GetKey(_keyCo llection.IndexOfValue(valu e)))
End Sub
End Class
Shawn

"Michael K. Walter" <mk******@sqlcraft.com> wrote in message
news:e3**************@TK2MSFTNGP12.phx.gbl...
Thanks for the note Shawn.

I've tried a number of options (including your suggestion) and, while I

can
set this up using various collection types as my base, I still end up in
situation where I have to have the end users of my collection cast to the
appropriate type inside of the For-each loop. So far, I've had it return
either a DictionaryEntry or generic Object type in the For-Each that I had to manipulate/cast to MyObj type before using the retrieved object. I was trying to avoid this but I'm beginning to think that this cannot be done

in
.Net (like I can in VB6).

Example:

Dim d1 as New Dog("Duncan","Golden Retriever")
Dim d2 as New Dog("Louie", "Lab")
Dim d3 as New Dog("Butch","Beagle")

Dim Kennel as New DogCollection

Kennel.Add(d1)
Kennel.Add(d2)
Kennel.Add(d3)

Dim o as Object
Dim d as Dog

For Each o In Kennel
d = CType(o, Dog)
Console.Write(d.Name)
Next

But I'm trying to get the last lines to look like this (no Object variable declaration or Cast required):

Dim D as Dog

For Each d in Kennel
Console.Write(d.Name)
Next

Even using IEnumerable/IEnumerator didn't help since the IEnumerator
Current() property returns a generic Object type (and I couldn't get it
compile when I changed the return type to Dog).

Am I missing something?

Michael

"Shawn Hogan" <NOSPAM> wrote in message
news:eB**************@TK2MSFTNGP12.phx.gbl...
I ran into a similar problem the way that i solved it was to have a class that inherited from CollectionBase. This class also contained a

SortedList.
Anytime i added something to the list object of the collectionBase i added it to the sorted list. By doing this i was able to access my items by key
or
by index.

Shawn

"Michael K. Walter" <mk******@sqlcraft.com> wrote in message
news:eQ**************@tk2msftngp13.phx.gbl...
> I'd like to create a strongly-typed collection of objects that are

indexed
> by a string value (key is a string). I'd also like to allow users to
iterate
> over the collection using a For-each loop where an object of the

contained
> type is returned (instead of just the standard DictionaryEntry

object). >
> - only allow objects of type MyObj to be added to the collection
> - return a MyObj type in the For-each loop
>
> What's the best way to do this?
>
> I tried to have my collection class inherit from DictionaryBase but I had
> trouble getting it to return MyObj objects in the For-each. By
default its
> retruning DictionaryEntry objects and it wouldn't let me override

the > inherited GetEnumerator() function.
>
> I also looked at inheriting from CollectionBase but this takes an

integer
> for the key values.
>
> Is creating a class that implements IEnumerable and contains a private > collection object the way to go here?
>
> Thanks in advance for the help/advice.
>
> Michael
>
>



Nov 20 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.