473,406 Members | 2,208 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Creating a strongly-typed enumerable collection?

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
4 2503
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: andrea | last post by:
I was thinking to code the huffman algorithm and trying to compress something with it, but I've got a problem. How can I represent for example a char with only 3 bits?? I had a look to the...
5
by: | last post by:
Hi, i'm trying to run an .asp page to get an xml file off a server. I need to know what object to create. My page just runs till timeout...it bombs on the httpxml.send command. This is the code I...
8
by: cody | last post by:
i basically want to create an object which contains an array (the last element of the class). the size of the array is determined when the object is created. for performance reasons (avoiding...
3
by: Pattnayak | last post by:
Hi, I want to create a DTS package programatically (preferably in C#.net),which will copy all my tables from a oracle database to my sql-server database. Can anybody help me doing this??? Thanks...
4
by: Tamir Khason | last post by:
I have a form. On form there is my control (all of control's assemblies signed by strong key), BUT while running I recieve he located assembly 'MyFooAssembly' is not strongly named. While...
1
by: San | last post by:
Hi, Why strongly named assembly can refer other strongly named assembly ? Thanks with Regards, San.
5
by: Oleg Subachev | last post by:
When I try to use strongly named assembly1 that references non-strongly named assembly2 I get the following error: "The located assembly '<assembly2 name>' is not strongly named." How can I...
1
by: DotNetJunkies User | last post by:
I have a .NET DLL that uses ADO 2.8 DLL. I am not able to "strongly name" the .NET DLL. Any comments, work arounds ? CHDe --- Posted using Wimdows.net NntpNews Component -
11
by: melon | last post by:
Let's say, I have a form class... public class MainForm : Form { private CustomClass cc; public MainForm() { DoSomething() InitializeComponent(); } /// Do something more
0
by: Dave Burns | last post by:
Hi, I have a C++ managed assembly (.dll) which links to a bunch of native libraries. Everything works fine if I don't make the managed assembly a strongly named one. Once I make it a strongly...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.