C
Chris Mullins [MVP]
KeyedCollection is a very handy little class, that unforutnatly has a nasty
bug in it.
The bug (which I ran across) causes the following code to fail:
if (!rooms.Contains(room))
_rooms.Add(room);
The problem is that contains returns "false", but then Add throws an
exception because the item really is already in there.
The follow code illustrates the bug in the class:
static void Main(string[] args)
{
KeyTest foo = new KeyTest();
KeyedClass item1 = new KeyedClass("1", "99");
KeyedClass item2 = new KeyedClass("1", "99");
KeyedClass item3 = new KeyedClass("1", "100");
foo.Add(item1);
// this one fails
if (!foo.Contains(item2))
Console.WriteLine("Broken Based on Instancing!");
// this one fails
if (!foo.Contains(item3))
Console.WriteLine("Broken Based on Key Lookup!");
// this one works
if (!foo.Contains(item2.Key))
Console.WriteLine("Even Contains by Key Type is Broken");
}
class KeyTest : KeyedCollection<string, KeyedClass>
{
protected override string GetKeyForItem(KeyedClass item)
{
return item.Key;
}
}
class KeyedClass
{
public readonly string Key, Value;
public KeyedClass(string k, string v)
{
Key = k; Value = v;
}
}
bug in it.
The bug (which I ran across) causes the following code to fail:
if (!rooms.Contains(room))
_rooms.Add(room);
The problem is that contains returns "false", but then Add throws an
exception because the item really is already in there.
The follow code illustrates the bug in the class:
static void Main(string[] args)
{
KeyTest foo = new KeyTest();
KeyedClass item1 = new KeyedClass("1", "99");
KeyedClass item2 = new KeyedClass("1", "99");
KeyedClass item3 = new KeyedClass("1", "100");
foo.Add(item1);
// this one fails
if (!foo.Contains(item2))
Console.WriteLine("Broken Based on Instancing!");
// this one fails
if (!foo.Contains(item3))
Console.WriteLine("Broken Based on Key Lookup!");
// this one works
if (!foo.Contains(item2.Key))
Console.WriteLine("Even Contains by Key Type is Broken");
}
class KeyTest : KeyedCollection<string, KeyedClass>
{
protected override string GetKeyForItem(KeyedClass item)
{
return item.Key;
}
}
class KeyedClass
{
public readonly string Key, Value;
public KeyedClass(string k, string v)
{
Key = k; Value = v;
}
}