Domanda

Spesso mi trovo in una situazione in cui creo un'interfaccia o una classe generica e quindi voglio utilizzare versioni diverse di questa classe o interfaccia in modo non generico. Ad esempio potrei avere un'interfaccia come questa:

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

Che consente a una classe di essere una factory per quel tipo. Voglio quindi registrarli con una classe factory generale, quindi provo a scrivere qualcosa del genere:

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

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

    public T Create<T>()
    {            
    }
}

Nel dizionario quale tipo devo usare per il mio valore? Non so se mi manca una sorta di principio di progettazione e sono consapevole che questo ha molto a che fare con la varianza co (ntra?). Qualsiasi aiuto o idea sarebbe molto apprezzato.

È stato utile?

Soluzione

Devi solo usare object nella tua dichiarazione del dizionario (è tutto privato, e tu puoi verificare che non ci metterai mai il tipo sbagliato di cose) o dichiarare un non -generica ICanCreate interfaccia che ICanCreate<T> estende.

Fondamentalmente vuoi una relazione di tipo che non può essere espressa in C # - e ogni volta che succede, ti ritrovi con una soluzione leggermente spiacevole, ma sembra che tu possa isolare la bruttezza qui (cioè tenerlo all'interno della singola classe ).

Altri suggerimenti

È interessante notare che questo è un problema risolto in C # 4.0:

public interface ICanCreate<out T> // covariant
{
    T NewObject();
}

public class Factory
{
    private Dictionary<Type, ICanCreate<object>> mappings = new Dictionary<Type, ICanCreate<object>>();

    public void RegisterCreator<T>(ICanCreate<T> creator) where T:class
    {            
      mappings[typeof(T)] = creator;
    }

    public T Create<T>()
    {            
      ICanCreate<object> creator = mappings[typeof(T)];
      return (T) creator.NewObject(); // I do not think you can get rid of this cast
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top