
View Message Thread (7 replies)
| How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
 |
From: Rich P Date Posted: 6/28/2010 12:22:00 PM
I found
public class SimpleDictionary : IDictionary
for creating a custom collection object at this site:
http://msdn.microsoft.com/en-us/library/system.collections.idictionary.a
spx
The following is a simple class called MyClass (followed by
SimpleDictionary : IDictionary). I can add MyClass objects to
SimpleDictionary as is. But if I add the following members to
IDictionary <int, MyClass> -- then my test app complains that I am not
implementing the members. How do I emplement these members <int,
MyClass> ?
public class MyClass
{
public int EmpID;
public string EmpName;
public MyClass(int i, string s)
{
EmpID = i;
EmpName = s;
}
}
// This class implements a simple dictionary using an array of
DictionaryEntry objects (key/value pairs).
public class SimpleDictionary : IDictionary <int, MyClass>
{
// The array of items
private DictionaryEntry[] items;
private Int32 ItemsInUse = 0;
// Construct the SimpleDictionary with the desired number of items.
// The number of items cannot change for the life time of this
SimpleDictionary.
public SimpleDictionary(Int32 numItems)
{
items = new DictionaryEntry[numItems];
}
#region IDictionary Members
public bool IsReadOnly { get { return false; } }
public bool Contains(object key)
{
Int32 index;
return TryGetIndexOfKey(key, out index);
}
public bool IsFixedSize { get { return false; } }
public void Remove(object key)
{
if (key == null) throw new ArgumentNullException("key");
// Try to find the key in the DictionaryEntry array
Int32 index;
if (TryGetIndexOfKey(key, out index))
{
// If the key is found, slide all the items up.
Array.Copy(items, index + 1, items, index, ItemsInUse -
index - 1);
ItemsInUse--;
}
else
{
// If the key is not in the dictionary, just return.
}
}
public void Clear() { ItemsInUse = 0; }
public void Add(object key, object value)
{
// Add the new key/value pair even if this key already exists in
the dictionary.
if (ItemsInUse == items.Length)
throw new InvalidOperationException("The dictionary cannot
hold any more items.");
items[ItemsInUse++] = new DictionaryEntry(key, value);
}
public ICollection Keys
{
get
{
// Return an array where each item is a key.
Object[] keys = new Object[ItemsInUse];
for (Int32 n = 0; n < ItemsInUse; n++)
keys[n] = items[n].Key;
return keys;
}
}
public ICollection Values
{
get
{
// Return an array where each item is a value.
Object[] values = new Object[ItemsInUse];
for (Int32 n = 0; n < ItemsInUse; n++)
values[n] = items[n].Value;
return values;
}
}
public object this[object key]
{
get
{
// If this key is in the dictionary, return its value.
Int32 index;
if (TryGetIndexOfKey(key, out index))
{
// The key was found; return its value.
return items[index].Value;
}
else
{
// The key was not found; return null.
return null;
}
}
set
{
// If this key is in the dictionary, change its value.
Int32 index;
if (TryGetIndexOfKey(key, out index))
{
// The key was found; change its value.
items[index].Value = value;
}
else
{
// This key is not in the dictionary; add this key/value
pair.
Add(key, value);
}
}
}
private Boolean TryGetIndexOfKey(Object key, out Int32 index)
{
for (index = 0; index < ItemsInUse; index++)
{
// If the key is found, return true (the index is also
returned).
if (items[index].Key.Equals(key)) return true;
}
// Key not found, return false (index should be ignored by the
caller).
return false;
}
private class SimpleDictionaryEnumerator : IDictionaryEnumerator
{
// A copy of the SimpleDictionary object's key/value pairs.
DictionaryEntry[] items;
Int32 index = -1;
public SimpleDictionaryEnumerator(SimpleDictionary sd)
{
// Make a copy of the dictionary entries currently in the
SimpleDictionary object.
items = new DictionaryEntry[sd.Count];
Array.Copy(sd.items, 0, items, 0, sd.Count);
}
// Return the current item.
public Object Current { get { ValidateIndex(); return
items[index]; } }
// Return the current dictionary entry.
public DictionaryEntry Entry
{
get { return (DictionaryEntry)Current; }
}
// Return the key of the current item.
public Object Key { get { ValidateIndex(); return
items[index].Key; } }
// Return the value of the current item.
public Object Value { get { ValidateIndex(); return
items[index].Value; } }
// Advance to the next item.
public Boolean MoveNext()
{
if (index < items.Length - 1) { index++; return true; }
return false;
}
// Validate the enumeration index and throw an exception if the
index is out of range.
private void ValidateIndex()
{
if (index < 0 || index >= items.Length)
throw new InvalidOperationException("Enumerator is
before or after the collection.");
}
// Reset the index to restart the enumeration.
public void Reset()
{
index = -1;
}
}
public IDictionaryEnumerator GetEnumerator()
{
// Construct and return an enumerator.
return new SimpleDictionaryEnumerator(this);
}
#endregion
#region ICollection Members
public bool IsSynchronized { get { return false; } }
public object SyncRoot { get { throw new NotImplementedException();
} }
public int Count { get { return ItemsInUse; } }
public void CopyTo(Array array, int index) { throw new
NotImplementedException(); }
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
// Construct and return an enumerator.
return ((IDictionary)this).GetEnumerator();
}
#endregion
}
Rich
*** Sent via Developersdex http://www.developersdex.com ***

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Arne Vajhøj Date Posted: 6/28/2010 1:20:00 PM
On 28-06-2010 14:20, Rich P wrote:
> I found
>
> public class SimpleDictionary : IDictionary
>
> for creating a custom collection object at this site:
>
> http://msdn.microsoft.com/en-us/library/system.collections.idictionary.aspx
>
> The following is a simple class called MyClass (followed by
> SimpleDictionary : IDictionary). I can add MyClass objects to
> SimpleDictionary as is. But if I add the following members to
> idictionary<int, MyClass> -- then my test app complains that I am not
> implementing the members. How do I emplement these members<int,
> MyClass> ?
You are not making it easy for us - since you are not providing
the exact error message.
But a quick glance at the code indicates that some of the
methods implementing the interfaces need some generic types.
public icollection<int> Keys
public icollection<myclass> Values
ienumerator<int> IEnumerable.GetEnumerator()
Arne

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Rich P Date Posted: 6/28/2010 2:38:00 PM
>
But a quick glance at the code indicates that some of the
methods implementing the interfaces need some generic types.
public icollection<int> Keys
public icollection<myclass> Values
ienumerator<int> IEnumerable.GetEnumerator()
Arne
<
Thank you for your reply. I made a few changes (like class name to
MyClassCollection. I also applied your suggestions above. I made
everything that said key and <int> and everything that said Value
<MyClass>. I am getting 17 errors. Following are 3 of the errors (one
error is common to about 10 of the errors, the 3rd error is self
explanatory) and a relisting of my collection class with the changes
that I have made thus far (note: the whole point of this exercise is to
learn how to implement interfaces and interfaces with members):
Error 1 -- 'InterfaceDictionary.MyClassCollection' does not implement
interfacemember 'System.Collections.IEnumerable.GetEnumerator()'.
'InterfaceDictionary.MyClassCollection.GetEnumerator()' cannot implement
'System.Collections.IEnumerable.GetEnumerator()' because it does not
have the matching return type of 'System.Collections.IEnumerator'.
Error 2 -- 'InterfaceDictionary.MyClassCollection' does not implement
interface member
'system.collections.generic.ienumerable<system.collections.generic.keyva
luepair<int,interfacedictionary.myclass>>.GetEnumerator()'.
'InterfaceDictionary.MyClassCollection.GetEnumerator()' cannot implement
'system.collections.generic.ienumerable<system.collections.generic.keyva
luepair<int,interfacedictionary.myclass>>.GetEnumerator()' because it
does not have the matching return type of
'system.collections.generic.ienumerator<system.collections.generic.keyva
luepair<int,interfacedictionary.myclass>>'.
Error 11 -- 'IEnumerable.GetEnumerator' in explicit interface
declaration is not a member of interface
public class MyClassCollection : IDictionary <int, MyClass>
{
// The array of items
private DictionaryEntry[] items;
private Int32 ItemsInUse = 0;
//// Construct the SimpleDictionary with the desired number of items.
//// The number of items cannot change for the life time of this
SimpleDictionary.
public MyClassCollection(Int32 numItems)
{
items = new DictionaryEntry[numItems];
}
#region IDictionary Members
public bool IsReadOnly { get { return false; } }
public bool Contains(int key)
{
Int32 index;
return TryGetIndexOfKey(key, out index);
}
public bool IsFixedSize { get { return false; } }
public void Remove(int key)
{
if (key == null) throw new ArgumentNullException("key");
// Try to find the key in the DictionaryEntry array
Int32 index;
if (TryGetIndexOfKey(key, out index))
{
// If the key is found, slide all the items up.
Array.Copy(items, index + 1, items, index, ItemsInUse - index -
1);
ItemsInUse--;
}
else
{
// If the key is not in the dictionary, just return.
}
}
public void Clear() { ItemsInUse = 0; }
public void Add(int key, MyClass value)
{
// Add the new key/value pair even if this key already exists in the
dictionary.
if (ItemsInUse == items.Length)
throw new InvalidOperationException("The dictionary cannot hold
any more items.");
items[ItemsInUse++] = new DictionaryEntry(key, value);
}
public icollection<int> Keys
{
get
{
// Return an array where each item is a key.
//int[] keys = new int[ItemsInUse];
int[] keys = new int[ItemsInUse];
for (Int32 n = 0; n < ItemsInUse; n++)
keys[n] = items[n].Key;
return keys;
}
}
public icollection<myclass> Values
{
get
{
// Return an array where each item is a value.
MyClass[] values = new MyClass[ItemsInUse];
for (Int32 n = 0; n < ItemsInUse; n++)
values[n] = items[n].Value;
return values;
}
}
public int this[int key]
{
get
{
// If this key is in the dictionary, return its value.
Int32 index;
if (TryGetIndexOfKey(key, out index))
{
// The key was found; return its value.
return items[index].Value;
}
else
{
// The key was not found; return null.
return 0;
}
}
set
{
// If this key is in the dictionary, change its value.
Int32 index;
if (TryGetIndexOfKey(key, out index))
{
// The key was found; change its value.
items[index].Value = value;
}
else
{
// This key is not in the dictionary; add this key/value pair.
Add(key, value);
}
}
}
private Boolean TryGetIndexOfKey(int key, out Int32 index)
{
for (index = 0; index < ItemsInUse; index++)
{
// If the key is found, return true (the index is also returned).
if (items[index].Key.Equals(key)) return true;
}
// Key not found, return false (index should be ignored by the
caller).
return false;
}
private class MyClassEnumerator : IDictionaryEnumerator
{
// A copy of the SimpleDictionary object's key/value pairs.
DictionaryEntry[] items;
Int32 index = -1;
public MyClassEnumerator(MyClassCollection sd)
{
// Make a copy of the dictionary entries currently in the
SimpleDictionary object.
items = new DictionaryEntry[sd.Count];
Array.Copy(sd.items, 0, items, 0, sd.Count);
}
// Return the current item.
public Object Current { get { ValidateIndex(); return items[index];
} }
// Return the current dictionary entry.
public DictionaryEntry Entry
{
get { return (DictionaryEntry)Current; }
}
// Return the key of the current item.
public Object Key { get { ValidateIndex(); return items[index].Key;
} }
// Return the value of the current item.
public Object Value { get { ValidateIndex(); return
items[index].Value; } }
// Advance to the next item.
public Boolean MoveNext()
{
if (index < items.Length - 1) { index++; return true; }
return false;
}
// Validate the enumeration index and throw an exception if the
index is out of range.
private void ValidateIndex()
{
if (index < 0 || index >= items.Length)
throw new InvalidOperationException("Enumerator is before or
after the collection.");
}
// Reset the index to restart the enumeration.
public void Reset()
{
index = -1;
}
}
public IDictionaryEnumerator GetEnumerator()
{
// Construct and return an enumerator.
return new MyClassEnumerator(this);
}
#endregion
#region ICollection Members
public bool IsSynchronized { get { return false; } }
public object SyncRoot { get { throw new NotImplementedException(); }
}
public int Count { get { return ItemsInUse; } }

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Arne Vajhøj Date Posted: 6/28/2010 3:40:00 PM
On 28-06-2010 16:36, Rich P wrote:
> Thank you for your reply. I made a few changes (like class name to
> MyClassCollection. I also applied your suggestions above. I made
> everything that said key and<int> and everything that said Value
> <MyClass>. I am getting 17 errors. Following are 3 of the errors (one
> error is common to about 10 of the errors, the 3rd error is self
> explanatory) and a relisting of my collection class with the changes
> that I have made thus far (note: the whole point of this exercise is to
> learn how to implement interfaces and interfaces with members):
>
> Error 1 -- 'InterfaceDictionary.MyClassCollection' does not implement
> interfacemember 'System.Collections.IEnumerable.GetEnumerator()'.
> 'InterfaceDictionary.MyClassCollection.GetEnumerator()' cannot implement
> 'System.Collections.IEnumerable.GetEnumerator()' because it does not
> have the matching return type of 'System.Collections.IEnumerator'.
> Error 2 -- 'InterfaceDictionary.MyClassCollection' does not implement
> interface member
> 'system.collections.generic.ienumerable<system.collections.generic.keyva
> luepair<int,interfacedictionary.myclass>>.GetEnumerator()'.
> 'InterfaceDictionary.MyClassCollection.GetEnumerator()' cannot implement
> 'system.collections.generic.ienumerable<system.collections.generic.keyva
> luepair<int,interfacedictionary.myclass>>.GetEnumerator()' because it
> does not have the matching return type of
> 'system.collections.generic.ienumerator<system.collections.generic.keyva
> luepair<int,interfacedictionary.myclass>>'.
>
> Error 11 -- 'IEnumerable.GetEnumerator' in explicit interface
> declaration is not a member of interface
The problem must be with those two:
> public IDictionaryEnumerator GetEnumerator()
> {
> // Construct and return an enumerator.
> return new MyClassEnumerator(this);
> }
> ienumerator<int> IEnumerable.GetEnumerator()
> {
> // Construct and return an enumerator.
> return ((IDictionary)this).GetEnumerator();
> }
They seems to have wrong return types compared to
the interfaces.
The easiest would probbaly be to ask your IDE to add the
missing methods and see the proper signature.
Arne

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Arne Vajhøj Date Posted: 6/28/2010 3:46:00 PM
On 28-06-2010 17:38, Arne Vajhøj wrote:
> On 28-06-2010 16:36, Rich P wrote:
>> Thank you for your reply. I made a few changes (like class name to
>> MyClassCollection. I also applied your suggestions above. I made
>> everything that said key and<int> and everything that said Value
>> <MyClass>. I am getting 17 errors. Following are 3 of the errors (one
>> error is common to about 10 of the errors, the 3rd error is self
>> explanatory) and a relisting of my collection class with the changes
>> that I have made thus far (note: the whole point of this exercise is to
>> learn how to implement interfaces and interfaces with members):
>>
>> Error 1 -- 'InterfaceDictionary.MyClassCollection' does not implement
>> interfacemember 'System.Collections.IEnumerable.GetEnumerator()'.
>> 'InterfaceDictionary.MyClassCollection.GetEnumerator()' cannot implement
>> 'System.Collections.IEnumerable.GetEnumerator()' because it does not
>> have the matching return type of 'System.Collections.IEnumerator'.
>
>> Error 2 -- 'InterfaceDictionary.MyClassCollection' does not implement
>> interface member
>> 'system.collections.generic.ienumerable<system.collections.generic.keyva
>> luepair<int,interfacedictionary.myclass>>.GetEnumerator()'.
>> 'InterfaceDictionary.MyClassCollection.GetEnumerator()' cannot implement
>> 'system.collections.generic.ienumerable<system.collections.generic.keyva
>> luepair<int,interfacedictionary.myclass>>.GetEnumerator()' because it
>> does not have the matching return type of
>> 'system.collections.generic.ienumerator<system.collections.generic.keyva
>> luepair<int,interfacedictionary.myclass>>'.
>>
>> Error 11 -- 'IEnumerable.GetEnumerator' in explicit interface
>> declaration is not a member of interface
>
> The problem must be with those two:
>
>> public IDictionaryEnumerator GetEnumerator()
>> {
>> // Construct and return an enumerator.
>> return new MyClassEnumerator(this);
>> }
>
>> ienumerator<int> IEnumerable.GetEnumerator()
>> {
>> // Construct and return an enumerator.
>> return ((IDictionary)this).GetEnumerator();
>> }
>
> They seems to have wrong return types compared to
> the interfaces.
>
> The easiest would probbaly be to ask your IDE to add the
> missing methods and see the proper signature.
I just did. They are supposed to be:
public ienumerator<keyvaluepair<int, MyClass>> GetEnumerator()
IEnumerator IEnumerable.GetEnumerator()
Arne

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Rich P Date Posted: 6/28/2010 3:52:00 PM
>
They seems to have wrong return types compared to
the interfaces.
The easiest would probbaly be to ask your IDE to add the
missing methods and see the proper signature.
Arne
<
I'm using VS2008 Pro. How would I go about asking the IDE to add the
missing methods? I don't mind recreating the class. It's not that big.
I started kicking around with MVC, and when you start an MVC project
(asp.net) the IDE sets up all sorts of classes and stuff by default.
Are you suggesting default stuff? I guess I should add that in addition
to learning about implementing interfaces and members, I am sure there
is still a lot I need to learn about the IDE. Any suggestions
appreciated on how to perform the operation of adding the missing
methods.
Rich
*** Sent via Developersdex http://www.developersdex.com ***

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Arne Vajhøj Date Posted: 6/28/2010 4:09:00 PM
On 28-06-2010 17:50, Rich P wrote:
>> They seems to have wrong return types compared to
>> the interfaces.
>>
>> The easiest would probbaly be to ask your IDE to add the
>> missing methods and see the proper signature.
> I'm using VS2008 Pro. How would I go about asking the IDE to add the
> missing methods?
Right click and chose "implement interface - implement interface".
Edit the method bodies but keep the signatures as is.
Arne

| Re: How to implement IDictionary with <int, MyClass> members for custom Collection Object? |
|
From: Rich P Date Posted: 6/28/2010 4:37:00 PM
Thank you very much. I had to do that same operation with the
interfaces with this sample MVC project I was practicing with. On the
exercise for this post -- this operation has now reinforced how to
implement interfaces with the right-click menu. I decided to start the
class over from scratch with just the signature and then implement the
interface from the right-click menu as you suggested. I think I can
take it from here.
Many thanks again for the help.
Rich
*** Sent via Developersdex http://www.developersdex.com ***

Would you like to track this thread?
By adding this News Thread to your Favorites Area you can refer to it later with just a click of the mouse.
Also you can optionally be notified instantly whenever there are any replies
posted to this Thread. To add this Thread to your Favorites Area just click on the red arrow next to the subject of the thread above
.
|