2010-05-19 9 views
4

J'ai cette conception:Comment puis-je faire fonctionner cette simple usine de génériques C#?

public interface IFactory<T> { 
    T Create(); 
    T CreateWithSensibleDefaults(); 
} 

public class AppleFactory : IFactory<Apple> { ... } 
public class BananaFactory : IFactory<Banana> { ... } 
// ... 

fictif Apple et Banana ici ne partagent pas nécessairement tous les types communs (autres que object, bien sûr).

Je ne veux pas que les clients dépendent d'usines spécifiques, donc à la place, vous pouvez simplement demander un FactoryManager pour un nouveau type. Il a une méthode FactoryForType:

IFactory<T> FactoryForType<T>(); 

Maintenant, vous pouvez appeler les méthodes d'interface appropriées avec quelque chose comme FactoryForType<Apple>().Create(). Jusqu'ici tout va bien.

Mais il y a un problème au niveau de l'implémentation: comment est-ce que je stocke cette correspondance des types à IFactory<T>? La réponse naïve est un IDictionary<Type, IFactory<T>>, mais cela ne fonctionne pas car il n'y a pas de covariance de type sur le T (j'utilise C# 3.5). Suis-je juste coincé avec un IDictionary<Type, object> et faire le casting manuellement?

Répondre

5

Malheureusement oui vous êtes coincé avec la coulée manuelle. Cependant, ce casting peut être un détail d'implémentation et non vu par le consommateur. Par exemple

public class FactoryMap { 
    private Dictionary<Type,object> _map = new Dictionary<Type,object>(); 
    public void Add<T>(IFactory<T> factory) { 
    _map[typeof(T)] = factory; 
    } 
    public IFactory<T> Get<T>() { 
    return (IFactory<T>)_map[typeof(T)]; 
    } 
} 
+0

@code poète, 26 secondes :) – JaredPar

+0

Merci! C'est à propos de ce que j'ai maintenant; Je pensais qu'il n'y avait pas beaucoup de marge de manœuvre avec accès à la covariance. –