.Net中KeyedByTypeCollection的使用?

时间:2008-12-01 09:45:07

标签: .net .net-3.5

在.net中查看泛型集合时,我发现了KeyedByTypeCollection。虽然我使用它并且知道如何使用它,但我没有得到它会有用的情况。

我通读ServiceProvider, cache etc. done with generics without cast,但收不到多少。

我认为,必须有一个理由说明为什么它被包含在.Net框架中。使用KeyedByTypeCollection的任何团体都可以解释为什么他们使用它或任何身体,如果他们知道可以使用哪种情况,可以向我解释。

更多的好奇心是否有其他语言支持这种类型的收藏?

3 个答案:

答案 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;是解决单身人士问题的另一种方法。

主要有三种方法:

  1. 在每个类中实现CurrentInstance属性 - 意味着重复的代码很多。这很糟糕。

  2. 实施Singleton<T>基类 - 意味着您可以class A : Singleton<B>显然是错误的。

  3. 实施SingletonFactory - 这是有据可查的。我在大约12个月前就想到了这一点,并且坦率地惊讶地发现它是Java世界中一个非常好的主题。我为当前客户端编写的那个没有接口限制,并且是静态的,这意味着它可以锁定集合以保证线程安全。如果不使它成为静态,你就有可能获得两个不同对象的相同类型的单体。

答案 2 :(得分:0)

在分析此类课程时,我认为这完全无关紧要。使用基类KeyedCollection并编写GetKeyForItem方法以返回Item参数的Type。

KeyedByTypeCollection上定义了四种不相关的方法(FindFindAllRemoveRemoveAll)。 Find,FindAll和RemoveAll 没有基本的KeyedCollection实现。 删除在基类中确实存在。

KeyedByTypeCollection中所有这四个方法的第一个问题是它们对基本Collection进行串行搜索以找到该项目。为什么不只使用KeyedCollection中的索引器来检索适当的项目呢?

第二,FindAllRemoveAll只会找到1个项目(如果集合中存在一个项目)-因为按DEFINITION,只有一个指定类型的项目将存在于集合中(哦,和FindAll将连续读取Collection中的所有元素,即使它在开头找到匹配的元素也是如此。因此,FindAllRemoveAll将在查找/删除0或1个项目之前读取集合中的所有项目。同样,为什么不使用索引器或基本版本的Remove来执行所需的过程?

该类的第二个问题是它没有被设计为基类(换句话说,除非您知道如何编写方法的内部结构,否则不要从其继承)。在应该使用GetKeyForItem方法的地方没有调用,因此,如果您覆盖GetKeyForItem方法,则还必须覆盖其他几种方法以正确获取Collection的键。 / p>