在.net中查看泛型集合时,我发现了KeyedByTypeCollection。虽然我使用它并且知道如何使用它,但我没有得到它会有用的情况。
我通读ServiceProvider, cache etc. done with generics without cast,但收不到多少。
我认为,必须有一个理由说明为什么它被包含在.Net框架中。使用KeyedByTypeCollection的任何团体都可以解释为什么他们使用它或任何身体,如果他们知道可以使用哪种情况,可以向我解释。
更多的好奇心是否有其他语言支持这种类型的收藏?
答案 0 :(得分:13)
AFAIK,当KeyedCollection<KEY,VALUE>
是要存储的KEY
的类型时,此通用集合仅用作VALUE
的简单包装。
例如,如果您想要实现工厂返回的单身人士,那么使用此集合非常方便:
public class Factory<T>
{
private readonly KeyedByTypeCollection<T> _singletons = new KeyedByTypeCollection<T>();
public V GetSingleton<V>() where V : T, new()
{
if (!_singletons.Contains(typeof(V)))
{
_singletons.Add(new V());
}
return (V)_singletons[typeof(V)];
}
}
使用这个简单的工厂将如下所示:
[Test]
public void Returns_Singletons()
{
Factory<ICar> factory = new Factory<ICar>();
Opel opel1 = factory.GetSingleton<Opel>();
Opel opel2 = factory.GetSingleton<Opel>();
Assert.IsNotNull(opel1);
Assert.IsNotNull(opel2);
Assert.AreEqual(opel1, opel2);
}
KeyedByTypeCollection<T>
的另一种用法是在服务定位器内......
答案 1 :(得分:3)
&#34;单身工厂&#34;是解决单身人士问题的另一种方法。
主要有三种方法:
在每个类中实现Current
或Instance
属性 - 意味着重复的代码很多。这很糟糕。
实施Singleton<T>
基类 - 意味着您可以class A : Singleton<B>
显然是错误的。
实施SingletonFactory
- 这是有据可查的。我在大约12个月前就想到了这一点,并且坦率地惊讶地发现它是Java世界中一个非常好的主题。我为当前客户端编写的那个没有接口限制,并且是静态的,这意味着它可以锁定集合以保证线程安全。如果不使它成为静态,你就有可能获得两个不同对象的相同类型的单体。
答案 2 :(得分:0)
在分析此类课程时,我认为这完全无关紧要。使用基类KeyedCollection
并编写GetKeyForItem
方法以返回Item参数的Type。
在KeyedByTypeCollection
上定义了四种不相关的方法(Find
,FindAll
,Remove
和RemoveAll
)。 Find,FindAll和RemoveAll 没有基本的KeyedCollection
实现。 删除在基类中确实存在。
KeyedByTypeCollection
中所有这四个方法的第一个问题是它们对基本Collection进行串行搜索以找到该项目。为什么不只使用KeyedCollection
中的索引器来检索适当的项目呢?
第二,FindAll
和RemoveAll
只会找到1个项目(如果集合中存在一个项目)-因为按DEFINITION,只有一个指定类型的项目将存在于集合中(哦,和FindAll
将连续读取Collection中的所有元素,即使它在开头找到匹配的元素也是如此。因此,FindAll
和RemoveAll
将在查找/删除0或1个项目之前读取集合中的所有项目。同样,为什么不使用索引器或基本版本的Remove来执行所需的过程?
该类的第二个问题是它没有被设计为基类(换句话说,除非您知道如何编写方法的内部结构,否则不要从其继承)。在应该使用GetKeyForItem
方法的地方没有调用,因此,如果您覆盖GetKeyForItem
方法,则还必须覆盖其他几种方法以正确获取Collection的键。 / p>