Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / VB.NET / January 2005

Tip: Looking for answers? Try searching our database.

Custom collection and For Each

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Michael Kellogg - 30 Jan 2005 07:02 GMT
I created a custom collection based on
System.Collections.Specialized.NameObjectCollectionBase.  I also
implemented two version of the "Item" property and coded them both as
Default properties.

Now, when I look at the data, everything looks good; the underlying objects
in there, and the Item property returns the same even if I just access like
this:  Label(i), so that is cool.

However, I tried to do a For...Each on the object just now and it's not
returning to me the underlying object (as is specified in the Item
properties).  Instead it's returning the string key for that element.

What gives?  I want to iterate through the collection with a For...Each but
cannot see what I'm doing wrong.

Appreciate any suggestions.

Signature

God Bless,
 Michael

Cor Ligthert - 30 Jan 2005 07:58 GMT
Michael.

Do you want to know what you are doing wrong in the code you did not show?

You see the code before you, how you think anybody can help you when he does
not know what you did. Therefore when you want help, show some code (piece
by piece the first time and first pasted in a noteback an copied back in
your message to make it readable)

Cor
Michael Kellogg - 30 Jan 2005 08:43 GMT
"Cor Ligthert" <notmyfirstname@planet.nl> wrote (in
microsoft.public.dotnet.languages.vb):

> Michael.
>
[quoted text clipped - 7 lines]
>
> Cor

Cor,

My, what a tactful guy you are.

Here is part of the collection of my custom object:
------------

Public Class FormLabels
   Inherits System.Collections.Specialized.NameObjectCollectionBase

   Default Public ReadOnly Property Item(ByVal index As Integer) As
FormLabel
       Get
           Return BaseGet(index)
       End Get
   End Property
   Default Public ReadOnly Property Item(ByVal FormCode As String) As
FormLabel
       Get
           Return BaseGet(FormCode)
       End Get
   End Property
...
End Class

---------
Here is the code where I try to iterate the collection:
---------
   Protected Sub RefreshForms()
       With lstForms.Items
           .Clear()
           Dim fl As FormLabel
           Dim fls As FormLabels
           fls = m_JobLabel.FormLabels     'pass the copy one time
           For Each fl In fls
               .Add(fl.FormCode + " (" + fl.FormNumber.ToString + ")")
           Next
       End With
   End Sub

------------
As it stands, I get an InvalidCastException at the "For Each" statement.  
I went back and changed fl's definition to "Object" and discovered that
it was handed a String (it is the element's key), not a FormLabel object.
What I don't get is what the "Each" clause goes and gets.  I assumed it
was the default property, which should return an object to me, not a
string.

I can work around this by iterating the collection manually, but I want
to know how to get the "Each" to work.

-Michael
Cor Ligthert - 30 Jan 2005 09:08 GMT
Michael,

> My, what a tactful guy you are.

Do if I did not ask to show your code.

I am sorry Michael, without your code I cannot help you.

Cor
Michael Kellogg - 30 Jan 2005 09:47 GMT
"Cor Ligthert" <notmyfirstname@planet.nl> wrote (in
microsoft.public.dotnet.languages.vb):

> Michael,

> Do if I did not ask to show your code.
>
> I am sorry Michael, without your code I cannot help you.
>
> Cor

?

I just supplied you with all the code in question, as you requested.  
Didn't you see all that below my initial comments?

- Michael
ABad - 30 Jan 2005 19:48 GMT
To handle "For Each" a collection must implement IEnumerable.
NameObjectCollectionBase already implements this interface and it looks like
the implementation iterates over the keys.

> "Cor Ligthert" <notmyfirstname@planet.nl> wrote (in
> microsoft.public.dotnet.languages.vb):
[quoted text clipped - 63 lines]
>
> -Michael
Michael Kellogg - 31 Jan 2005 19:13 GMT
> To handle "For Each" a collection must implement IEnumerable.
> NameObjectCollectionBase already implements this interface and it
> looks like the implementation iterates over the keys.

Let me ask this (I'm not familiar with the interfaces and have not found
any decent info about them, like IEnumerable):  Let's say this is what is
happening, that the For Each is enumerating the keys.  This makes the
iteration through my collection unusual, because I have to then use the
key that is returned to pull up the actual object inside the collection.  
In other words:
----------

dim key as string
for each key in MyObjects
 MyObjects(key).myProperty = x
next

----------
Is different than this standard implementation:
----------

dim obj as MyObject
for each obj in MyObjects
 obj.myProperty = x
next

----------
What I'm trying to understand is how to make it work in the latter case.
My Default property is ITEM, which returns an object (not the key
string).  What am I missing?

Signature

Michael Kellogg

ABad - 31 Jan 2005 20:14 GMT
> any decent info about them, like IEnumerable):  Let's say this is what is
> happening, that the For Each is enumerating the keys.

It is whats happening. I tested it and looked at the IL of the
NameObjectCollectionBase class.

> What I'm trying to understand is how to make it work in the latter case.
> My Default property is ITEM, which returns an object (not the key
> string).  What am I missing?

Like I said the "For Each" mechanism is dependent on the IEnumerable
interface, NOT Default property. For NameObjectCollectionBase class, the
implementation is enumerate over the keys. You cannot "elegantly" override
this behavior so you can't depend on NameObjectCollectionBase to do what you
want. Now you could "shadow" the GetEnumerator method and provide your own
implementation of IEnumerator but you should read up on what "shadows" does
before you take this step.

What I would do for an "elegant" design is implement my own class that
implements the ICollection interface. Expose all methods necessary and defer
the implementation details to an existing .NET data structure that supplies
the needed functionality, say hashtable. I would then implement IEnumerable
with my own implementation.

- ABad

> > To handle "For Each" a collection must implement IEnumerable.
> > NameObjectCollectionBase already implements this interface and it
[quoted text clipped - 26 lines]
> My Default property is ITEM, which returns an object (not the key
> string).  What am I missing?

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.