[Mono-dev] Key matching issue in generic Dictionary [correct message]
Generic 2006
generic2006 at libero.it
Wed Aug 23 10:17:59 EDT 2006
Hi all
I'm facing a strange behavior affecting System.Collections.Generic.Dictionary<TKey,TValue>: when I try to search for a key among the dictionary entries using interface members such as ContainsKey(<TKey> key) or this[<TKey> key] I receive wrong responses (the key can't be find, whilst it's really there!).
I supposed that it could be a problem on the TKey side (where I implemented System.IEquatable<TKey>), so I put some Console.WriteLine()
inside the code to verify. A System.Collections.Generic.Dictionary instance is incapsulated in MyDictionary (an implementation of generic IDictionary), TKey is assigned to Name type, TValue is irrelevant.
class Name : IEquatable<Name>
{
public Name(string value)
{
...
}
public bool Equals(Name obj)
{
Console.WriteLine("Name.Equals(): this: " + this.value + " other: " + obj.Value);
return this.value.Equals(obj.Value);
}
public string Value
{
get{return this.value;}
}
}
class MyDictionary : IDictionary<Name,Object>
{
protected Dictionary<Name,Object> entries = new Dictionary<Name,Object>();
...
public bool ContainsKey(Name key)
{
Console.WriteLine("MyDictionary.ContainsKey: key = " + key.Value);
return this.entries.ContainsKey(key);
}
public Object this[Name key]
{
get
{
try
{
Console.WriteLine("Dictionary[]: key = " + key.Value);
return ((Object) this.entries[key]);
}
catch(Exception e)
{
Console.WriteLine("Dictionary[]:exception: " + e.Message);
foreach(KeyValuePair<PdfName,Object> kv in this.entries)
{
Console.WriteLine("PdfDictionary[]: pair: key = " + kv.Key.Value + " equals : " + key.Equals(kv.Key));
}
return null;
}
}
}
...
}
Here's the test I made:
1) populate MyDictionary with 3 entry pairs, whose keys are: Name("Info"), Name("Root"), Name("Size");
2) try to find Name("Encrypt") among MyDictionary keys, invoking MyDictionary.ContainsKey(Name key) method and obtaining such console output:
MyDictionary.ContainsKey: key = Encrypt
Name.Equals(): this: Encrypt other: Info
Name.Equals(): this: Encrypt other: Root
3) as you can see from the previous step, it strangely missed to invoke Name.Equals for the Name("Size") instance (just considered Name("Info") and Name("Root"): why?
4) try to get the object related to the Name("Size") key invoking MyDictionary.this[Name key] method and obtaining such console output:
Dictionary[]: key = Size
Dictionary[]:exception: The given key was not present in the dictionary.
Name.Equals(): this: Size other: Info
Dictionary[]: pair: key = Info equals : False
Name.Equals(): this: Size other: Root
Dictionary[]: pair: key = Root equals : False
Name.Equals(): this: Size other: Size
Dictionary[]: pair: key = Size equals : True
5) as you can see from the previous step, before the exception message there is NO invocation to Name.Equals() method, despite the invocation to this.entries[key] which should trigger the equality comparison. Then the iteration through all the keys yelds the expected result (Name("Size") key exists and is positively equated -- so the problem is NOT in IEquatable<Name> implementation!).
So, the problem seems to be that System.Collections.Generic.Dictionary<TKey,TValue> has a faulty way to access its keys...
What do you suggest about it?
Is it a reported bug?
How can I obtain the correct behavior?
Many thanks
More information about the Mono-devel-list
mailing list