Uses of KeyedByTypeCollection in .Net?

While checking out the generic collection in .net i found about KeyedByTypeCollection. Although I worked with it and got to know how to use it, I did not get in which scenario it will be useful.

I read through ServiceProvider, cache etc. done with generics without cast, but could not get much.

I think, there must have a reason as to why it has been included in the .Net framework. Any body who have used the KeyedByTypeCollection can explain me why they used it or any body, if they know in which scenario potentially it can be used, can explain it to me.

As more of a curiosity does any other languages support this type of collection ?

AFAIK, this generic collection serves just as a simple wrapper for KeyedCollection<KEY,VALUE> when KEY is the Type of the VALUE to store.

For example, it is very convinient to use this collection if you want to implement a factory returning singletons:

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

The use of this simple factory would be something like the following:

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

Another usage for KeyedByTypeCollection<T> would be inside a service locator...

KeyedByTypeCollection<TItem> Class, Recently a colleague of mine mentioned that he has just learned about KeyedByTypeCollection , although it has been included with .NET  The default equality comparer is used to compare keys. Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>, IEqualityComparer<TKey>) Correlates the elements of two sequences based on matching keys. A specified IEqualityComparer<T> is used to compare keys.

The "singleton factory" is a different approach to the problem of singletons.

There are three main approaches:

  1. Implement a Current or Instance property in every class - means a lot of repeated code. Which is bad.

  2. Implement a Singleton<T> base class - means you can have class A : Singleton<B> which is clearly wrong.

  3. Implement a SingletonFactory - this is well documented. I thought it up about 12 months ago and was frankly surprised to find it to be a very well covered subject in the Java world. The one I've written for my current client has no interface restrictions, and is static, which means it has a lock around the collection for thread safety. Without making it static, you risk getting two singletons of the same type that are different objects.

Ready to Use Dictionary for Objects of Different Types, Alternative to KeyedByTypeCollection in Mono .Net. I need a factory to Because the default IEqualityComparer for dictionaries uses the most  Initializes a new instance of the KeyedByTypeCollection<TItem> class for a specified enumeration of objects. public: KeyedByTypeCollection (System::Collections::Generic::IEnumerable<TItem> ^ items); C#. public KeyedByTypeCollection (System.Collections.Generic.IEnumerable<TItem> items); new System.Collections.Generic.KeyedByTypeCollection<'Item> : seq<'Item> -> System.Collections.Generic.KeyedByTypeCollection<'Item>.

In analyzing this class, my take is that it is totally irrelevant. Use the base class KeyedCollection and write the GetKeyForItem method to return the Type of the Item parameter.

There are four methods defined on the KeyedByTypeCollection that are irrelevant (Find, FindAll, Remove, and RemoveAll). Find, FindAll, and RemoveAll have no base KeyedCollection implementations. Remove does exist in the base class.

The first problem with all four of these methods in the KeyedByTypeCollection is that they perform a serial search of the base Collection to find the item(s). Why not just use the indexer from KeyedCollection to retrieve the appropriate item?

Second, FindAll and RemoveAll will only ever find 1 item (if one exists in the Collection) - because BY DEFINITION, only one item of the specified Type will exist in the Collection (oh, and FindAll will serially read through all the elements in the Collection, even if it finds the matching element at the beginning). So, FindAll and RemoveAll will read ALL the items in the Collection before either Finding/Removing 0 or 1 item(s). Again, why not use the indexer or the base version of Remove to perform the required process?

The second problem with the class is that it is not designed to be a base class (in other words, don't inherit from it unless you know how the internals of the methods are written). There are no calls to the GetKeyForItem method in places where it should be used, so, if you override the GetKeyForItem method, you must also override several other methods to properly get the key for the Collection.

Alternative to KeyedByTypeCollection in Mono .Net, Serialization; public class KeyedByTypeCollection : KeyedCollection { public SetItem(index, item); } } } // File provided for Reference Use Only by Microsoft  To use KeyedCollection<TKey,TItem>, derive your collection type from the appropriate constructed type. The KeyedCollection<TKey,TItem> class is a hybrid between a collection based on the IList<T> generic interface and a collection based on the IDictionary<TKey,TValue> generic interface.

KeyedByTypeCollection.cs source code in C# .NET, KeyedByTypeCollection<TItem> Class. // .NET Framework 3.0 // System. Usage. Metadata. ID: T:System.Collections.Generic.KeyedByTypeCollection`1  Alternative to KeyedByTypeCollection in Mono .Net. I need a factory to create singletons. Usually I would do this with something similar to public class Factory<T> { readonly KeyedByTypeCollection<T> singletons = new KeyedByTypeCollection (); public U GetSingleton<U> () where U : T, new () { if (!singletons.Contains (typeof (U))) { singletons.Add (new U ()); } return (U)singletons [typeof (U)]; } }

KeyedByTypeCollection<TItem>, To rely on the host base address, provide an empty string if you want to use only the Uri tcpBaseAddress = new Uri("net.tcp://localhost:8000/"); ServiceHost host Open(); public class KeyedByTypeCollection<T> : KeyedCollection<Type,T>  In this article. Definition. Applies to. Removes all of the elements of a specified type from the collection. public: generic <typename T> System::Collections::ObjectModel::Collection<T> ^ RemoveAll (); C#. public System.Collections.ObjectModel.Collection<T> RemoveAll<T> (); member this.RemoveAll : unit -> System.Collections.ObjectModel.Collection<'T>.

Programming WCF Services, NET generics don't have any way of expressing this, and you end up with Pavel: I can't say I've used KeyedByTypeCollection before, but it  Top 10 Uses of .Net: Some of the main uses are explained in detail are as follows: Architecture: .net is having multi-tiered software architecture. It helps in separating the functions for presentation, processing of application and data management. It is being used for developing flexible applications.

Comments
  • Thanks, for the nice usage you have provided here.
  • Why would a factory want to return singletons?