How do I use foreach to write each item when inheriting from NameObjectCollectionBase

T

Tony Johansson

Hi!

The complete source code is included.
Here in main I first fill a ListDictionary with some items then I
instansiate a new object of type
MyCollection which is derived from NameObjectCollectionBase.
In the C-tor of MyCollection I add all the items in the ListDirectory to the
baseclass using
this.BaseAdd((String)de.Key, de.Value );

Then in main a pass the object of type MyCollection to a static method
called PrintKeysAndValues
where I want to use foreach to write both the key and the value.
In the original code they use an indexer in this way
public DictionaryEntry this[ int index ]
{
get
{
return ( new DictionaryEntry( this.BaseGetKey(index),
this.BaseGet(index) ) );
}
}
which is called from PrintKeysAndValues and works as expected.
I can use the original way to write key and value and be happy with that but
I want to understand why I can't use the foreach because the baseclass
NameObjectCollectionBase do supply one which I have hopped to use in my
derived class MyCollection but it doesnt't work because the element that I
think is a DictioneryEntry is string so that give runtime error.
I have also tried to use this way but this will only write the value. I have
hopped that this current here would have been
a DictionaryEntry but it's a string.
IEnumerator e = myCol.GetEnumerator();
while (e.MoveNext())
Console.WriteLine(e.Current);

So can somebody explain why it's not possible to a foreach when the
baseclass have one that that derived class can inherit and use ??

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Collections;


public class SamplesNameObjectCollectionBase
{
public static void Main()
{
IDictionary d = new ListDictionary();
d.Add("red", "apple");
d.Add("yellow", "banana");
d.Add("green", "pear");
MyCollection myROCol = new MyCollection(d, true);
PrintKeysAndValues(myROCol);
}


public static void PrintKeysAndValues(MyCollection myCol)
{
IEnumerator e = myCol.GetEnumerator();
while (e.MoveNext())
Console.WriteLine(e.Current);

foreach (DictionaryEntry item in myCol)
{
Console.WriteLine("Key={0}, Value = {1}", item.Key, item.Value);
}

//This code work
//for (int i = 0; i < myCol.Count; i++)
//{
// Console.WriteLine("[{0}] : {1}, {2}", i, myCol.Key,
myCol.Value);
//}
}
}


public class MyCollection : NameObjectCollectionBase
{
public MyCollection() {}

public MyCollection( IDictionary d, Boolean bReadOnly )
{
foreach ( DictionaryEntry de in d )
{
this.BaseAdd((String)de.Key, de.Value );
}
this.IsReadOnly = bReadOnly;
}
}


public DictionaryEntry this[ int index ]
{
get { return ( new DictionaryEntry( this.BaseGetKey(index),
this.BaseGet(index) ) ); }
}
}

//Tony
 
P

Peter Duniho

Tony said:
[...]
I can use the original way to write key and value and be happy with that but
I want to understand why I can't use the foreach because the baseclass
NameObjectCollectionBase do supply one which I have hopped to use in my
derived class MyCollection but it doesnt't work because the element that I
think is a DictioneryEntry is string so that give runtime error.
I have also tried to use this way but this will only write the value. I have
hopped that this current here would have been
a DictionaryEntry but it's a string.
IEnumerator e = myCol.GetEnumerator();
while (e.MoveNext())
Console.WriteLine(e.Current);

So can somebody explain why it's not possible to a foreach when the
baseclass have one that that derived class can inherit and use ??

You've already answered the question. It's because the enumerator for
NameObjectCollectionBase doesn't enumerate key/value pairs, but rather
just the keys. This is documented:
http://msdn.microsoft.com/en-us/lib...d.nameobjectcollectionbase.getenumerator.aspx

NameObjectCollectionBase doesn't implement any dictionary interface that
would allow paired enumeration. If you want to retrieve keys and values
in pairs, you can:

– Use the indexer as you've shown in your own code
– Enumerate the keys, and use the BaseGet(String) method overload to
get each value for each key
– Call the BaseGetAllKeys() and BaseGetAllValues() methods to get a
pair of arrays you can enumerate in parallel

Pete
 

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

Similar Threads

NameObjectCollectionBase 3

Top