KeyedByTypeCollection 在 .Net 中的用途是什么?

10

在查看.net通用集合时,我发现了KeyedByTypeCollection。虽然我已经使用它并知道如何使用它,但我不知道它在哪种情况下会有用。

我阅读了ServiceProvider、缓存等用泛型完成而不需要转换,但没有得到很多信息。

我认为,它被包含在.NET框架中一定有其原因。任何已经使用过KeyedByTypeCollection的人都可以解释一下他们为什么使用它,或者如果他们知道潜在的使用场景,也可以向我解释。

只是出于好奇,其他语言是否支持这种类型的集合?

3个回答

14
据我所知,这个通用集合仅作为一个简单的包装器,用于存储类型为VALUEKEYedCollection<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
感谢您在这里提供的良好使用体验。 - Biswanath
为什么工厂要返回单例? - user76071

3
“单例工厂”是解决单例问题的另一种方法。
主要有三种方法: 1.在每个类中实现“Current”或“Instance”属性——意味着很多重复的代码。这很糟糕。 2.实现一个Singleton基类——这意味着你可以有class A:Singleton,这显然是错误的。 3.实现一个SingletonFactory——这是一个被充分记录的主题。我大约在12个月前想出了这个方法,但惊讶地发现Java世界已经涵盖了它。我为我的客户编写的版本没有接口限制,并且是静态的,这意味着它在集合周围有一个锁以确保线程安全。如果不将其设置为静态,则可能会得到两个类型相同但却是不同对象的单例。

1
在分析这个类时,我的看法是它完全不相关。使用基类KeyedCollection并编写GetKeyForItem方法返回Item参数的类型。 KeyedByTypeCollection定义了四个方法是无关紧要的(Find, FindAll, Remove, 和RemoveAll)。Find, FindAll和RemoveAll没有基本KeyedCollection实现。Remove在基类中存在。 KeyedByTypeCollection中所有这四种方法的第一个问题是它们对基本集合执行串行搜索以查找项目。为什么不只是使用索引器从KeyedCollection检索适当的项目呢?
其次,FindAllRemoveAll仅会查找1个项目(如果集合中存在一个项目)-因为根据定义,只有指定类型的1个项目将存在于集合中(哦,并且FindAll将在序列中读取所有元素,即使它在开头找到匹配的元素)。 因此,FindAllRemoveAll将在查找/删除0或1个项目之前读取集合中的所有项目。 再次强调,为什么不使用索引器或Remove的基本版本执行所需的过程?
该类的第二个问题是它不是设计成基类(换句话说,除非你知道方法的内部工作原理,否则不要从中继承)。 在应该使用GetKeyForItem方法的地方没有调用,因此,如果覆盖GetKeyForItem方法,则还必须覆盖其他几个方法才能正确获取集合的键。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接