J'ai eu du mal à résoudre un problème similaire autour des classes de tables de données au lieu des messages. Le problème racine mentionné ci-dessus de la conversion d'une version non générique de la classe en une version générique dérivée était le même. Afin de permettre l'injection dans une bibliothèque de classes portable qui ne supportait pas les bibliothèques de bases de données, j'ai introduit un ensemble de classes d'interface, dans le but de pouvoir transmettre un type et obtenir un générique correspondant. Il a fini par avoir besoin d'implémenter une méthode générique.
// Interface for injection
public interface IDatabase
{
// Original, non-functional signature:
IDatatable<object> GetDataTable(Type dataType);
// Functional method using a generic method:
IDatatable<T> GetDataTable<T>();
}
Et cela l'ensemble de l'implémentation en utilisant la méthode générique ci-dessus.
La classe générique qui sera issue d'un dictionnaire.
// Non-generic base class allows listing tables together
abstract class Datatable
{
Datatable(Type storedClass)
{
StoredClass = storedClass;
}
Type StoredClass { get; private set; }
}
// Generic inheriting class
abstract class Datatable<T>: Datatable, IDatatable<T>
{
protected Datatable()
:base(typeof(T))
{
}
}
C'est la classe qui stocke la classe générique et il jette pour satisfaire la méthode générique dans l'interface
class Database
{
// Dictionary storing the classes using the non-generic base class
private Dictionary<Type, Datatable> _tableDictionary;
protected Database(List<Datatable> tables)
{
_tableDictionary = new Dictionary<Type, Datatable>();
foreach (var table in tables)
{
_tableDictionary.Add(table.StoredClass, table);
}
}
// Interface implementation, casts the generic
public IDatatable<T> GetDataTable<T>()
{
Datatable table = null;
_tableDictionary.TryGetValue(typeof(T), out table);
return table as IDatatable<T>;
}
}
Et enfin l'appel de la méthode d'interface.
IDatatable<CustomerAccount> table = _database.GetDataTable<CustomerAccount>();
La question suivante a un scénario de coulée évité en utilisant des génériques - [Code refactoring pour éviter clichage] (http://stackoverflow.com/questions/21482850/refactoring-code-to-avoid-type-casting) – Lijo