Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non Generic Versions of Generic classes and interfaces

I often find myself in a situation where I create a generic interface or class and then want to use different versions of this class or interface in a non generic way. For example I may have an interface like this:

interface ICanCreate<T>
{
    T NewObject();
}

Which allows a class to be a factory for that type. I then want to register these with a general factory class, so I try to write something like this:

public class Factory
{
    private Dictionary<Type, ICanCreate> mappings; // what do I put here????

    public void RegisterCreator<T>(ICanCreate<T> creator)
    {            
    }

    public T Create<T>()
    {            
    }
}

In the dictionary which type do I use for my value? I don't know if I am missing some sort of design principle and I am aware that this has a lot to do with co(ntra?)variance. Any help or ideas would be much appreciated.

like image 829
Jack Ryan Avatar asked Jun 17 '09 08:06

Jack Ryan


People also ask

What is generic and non-generic classes?

A Generic collection is a class that provides type safety without having to derive from a base collection type and implement type-specific members. A Non-generic collection is a specialized class for data storage and retrieval that provides support for stacks, queues, lists and hashtables.

Can a non-generic class implement a generic interface?

It is possible to create a non-generic class that implements a generic interface, provided that the type parameters are provided.

What is a non-generic class?

Non-generic, in other words, concrete, classes can inherit from closed constructed base classes, but not from open constructed classes or from type parameters because there is no way at run time for client code to supply the type argument required to instantiate the base class.

What is generics and non generics in Java?

Code Reuse: With help of Generics, one needs to write a method/class/interface only once and use it for any type whereas, in non-generics, the code needs to be written again and again whenever needed.


1 Answers

You either have to just use object in your dictionary declaration (it's all private, and you can verify that you'll never put the wrong kind of thing in there) or declare a non-generic ICanCreate interface which ICanCreate<T> extends.

Basically you want a type relationship which can't be expressed in C# - and whenever that happens, you end up with a slightly unpleasant solution, but it looks like you can isolate the ugliness here (i.e. keep it within the single class).

like image 161
Jon Skeet Avatar answered Sep 22 '22 21:09

Jon Skeet