框架错误:KeyedCollection< T> [英] Framework Bug: KeyedCollection<T>

查看:70
本文介绍了框架错误:KeyedCollection< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

KeyedCollection是一个非常方便的小班,它在它中有一个令人讨厌的

错误。


这个错误(我遇到过)会导致以下代码失败:


if(!rooms.Contains(room))

_rooms.Add(room);


问题是包含返回false,但是然后Add会抛出一个

异常,因为该项目已经存在。


以下代码说明了该类中的错误:


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);


//这个失败

if(!foo.Contains(item2))

Console.WriteLine(" Broken基于Instancing!);


//这个失败

if(!foo.Contains(item3))

Console.WriteLine(" Broken基于Key Lookup!);


//这一个工作

if(!foo.Contains(item2.Key))

Console.WriteLine(按键类型包含偶数已损坏);

}


类KeyTest:KeyedCollection< string,KeyedClass>

{

protected override string GetKeyForItem(KeyedClass item)

{

return item.Key;

}

}


class KeyedClass

{

public readonly string Key ,Value;

public KeyedClass(s​​tring k,string v)

{

Key = k;价值= v;

}

}


-

Chris Mullins,MCSD.NET ,MCPD:Enterprise,Microsoft C#MVP
http://www.coversant。 com / blogs / cmullins

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;
}
}

--
Chris Mullins, MCSD.NET, MCPD:Enterprise, Microsoft C# MVP
http://www.coversant.com/blogs/cmullins

推荐答案

我应该补充说,这是一个简单的解决方法。更改

具体KeyedCollection类以覆盖基础Contains方法工作

相当不错。不幸的是,每次创建一个键控集合类时,很少有人会想到这样做

...


类KeyTest:KeyedCollection< string, KeyedClass>

{

protected override string GetKeyForItem(KeyedClass item)

{

return item.Key; < br $>
}


公共新bool包含(KeyedClass项目)

{

返回此.Contains( item.Key);

}

}


-

Chris Mullins,MCSD。 NET,MCPD:Enterprise,Microsoft C#MVP
http://www.coversant .com / blogs / cmullins


" Chris Mullins [MVP]" < cm ****** @ yahoo.com在留言中写道

news:u6 ************** @ TK2MSFTNGP02.phx.gbl ...
I should add that there''s a straightforward workaround. Changing the
concrete KeyedCollection class to override the base Contains method works
pretty well. Unfortunatly, very few people are going to think to do this
every time they create a keyed collection class...

class KeyTest : KeyedCollection<string, KeyedClass>
{
protected override string GetKeyForItem(KeyedClass item)
{
return item.Key;
}

public new bool Contains(KeyedClass item)
{
return this.Contains(item.Key);
}
}

--
Chris Mullins, MCSD.NET, MCPD:Enterprise, Microsoft C# MVP
http://www.coversant.com/blogs/cmullins

"Chris Mullins [MVP]" <cm******@yahoo.comwrote in message
news:u6**************@TK2MSFTNGP02.phx.gbl...

KeyedCollection是一个非常方便的小班,它不可饶恕地有一个

令人讨厌的bug。


错误(我遇到过)导致以下代码失败:


if(!rooms.Contains(room))

_rooms.Add (房间);


问题是包含返回false,但是然后Add会抛出一个

异常,因为该项目已经存在。


以下代码说明了该类中的错误:


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.A dd(item1);


//这个失败

if(!foo.Contains(item2))

控制台。 WriteLine(Broken Based on Instancing!);


//这个失败

if(!foo.Contains(item3))

Console.WriteLine(基于键查找断开!);


//这个工作原理

if(! foo.Contains(item2.Key))

Console.WriteLine(按键类型包含偶数包含);

}


class KeyTest:KeyedCollection< string,KeyedClass>

{

protected override string GetKeyForItem(KeyedClass item)

{

返回item.Key;

}

}


class KeyedClass

{

public readonly string Key,Value;

public KeyedClass(s​​tring k,string v)

{

键= k;价值= v;

}

}


-

Chris Mullins,MCSD.NET ,MCPD:Enterprise,Microsoft C#MVP
http://www.coversant。 com / blogs / cmullins



Chris Mullins [MVP]< cm ****** @ yahoo.comwrote :
Chris Mullins [MVP] <cm******@yahoo.comwrote:

KeyedCollection是一个非常方便的小班,它在这个版本中有一个令人讨厌的

错误。
KeyedCollection is a very handy little class, that unforutnatly has a nasty
bug in it.



嗯......我不确定。

Hmm... I''m not sure.


这个错误(我遇到了)导致以下代码失败:


if(!rooms.Contains(room))

_rooms.Add(room);


问题是包含返回false,但是然后Add会抛出一个

异常,因为该项目已经存在。
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.



确实。


Contains方法用于检查给定的*键*是否在

集合。文档说GetKeyForItem用于查找每个元素的键

,但没有任何说明它用于获取

键的内容你传递给Contains的论点 - 这意味着已经确定

是关键。在你的情况下,它不是关键,它是一个项目。


另一方面,我很惊讶这个编译,鉴于你的类型/>
传递给Contains的意思是TKey类型,在你的示例代码中

你传递的是TItem实例。


嗯。当我有更多时间时会仔细看看。


-

Jon Skeet - < sk *** @ pobox.com>
< a rel =nofollowhref =http://www.pobox.com/~skeettarget =_ blank> http://www.pobox.com/~skeet 博客: http://www.msmvps.com/jon.skeet

如果回复小组,请不要给我发邮件

Indeed.

The Contains method is meant to check whether the given *key* is in the
collection. The docs say that GetKeyForItem is used to look up the key
for each element, but there''s nothing that state it''s used to get the
key for the argument you pass into Contains - that''s meant to already
be a key. In your case, it isn''t a key, it''s an item.

On the other hand, I''m surprised this compiles, given that the type you
pass to Contains is meant to be of type TKey, and in your sample code
you''re passing in an instance of TItem.

Hmm. Will look closer when I have more time.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Chris,
Chris,

> KeyedCollection is一个非常方便的小班,在这个问题上有一个令人讨厌的错误。
>KeyedCollection is a very handy little class, that unforutnatly has a nasty
bug in it.



我不认为这是一个错误。您必须在

KeyedClass中覆盖Equals,或者为

KeyedCollection for Contains提供自定义IEqualityComparer以按预期工作。


请注意前两个调用Contains最终调用

Collection< T> .Contains在基类中,确定

元素是否在Collection中 ; (即要求平等比较)。另一方面,

最后一次调用是KeyedCollection< TKey,

TItem> .Contains确定该集合是否包含

具有指定键的元素。

Mattias


-

Mattias Sj?gren [C#MVP] mattias @ mvps。 org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com

请回复到新闻组。

I don''t think it''s a bug. You have to override Equals in the
KeyedClass or provide a custom IEqualityComparer to the
KeyedCollection for Contains to work as expected.

Note that the first two calls to Contains end up calling
Collection<T>.Contains in the base class, which "determines whether an
element is in the Collection" (i.e. requires equality comparison). The
last call on the other hand is to KeyedCollection<TKey,
TItem>.Contains which "determines whether the collection contains an
element with the specified key".
Mattias

--
Mattias Sj?gren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


这篇关于框架错误:KeyedCollection&lt; T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆