Ho faticato a risolvere un problema simile attorno alle classi delle tabelle di dati anziché ai messaggi. Il problema di root menzionato sopra di trasmettere una versione non generica della classe a una versione generica derivata era la stessa.
Per consentire l'inserimento in una libreria di classi portatile che non supportava le librerie di database, ho introdotto un set di classi di interfaccia, con l'intento di poter passare un tipo e ottenere un generico corrispondente. Ha finito per dover implementare un metodo generico.
// 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>();
}
E questa l'intera implementazione utilizzando il metodo generico di cui sopra.
La classe generica che verrà trasmessa da un dizionario.
// 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))
{
}
}
Questa è la classe che memorizza la classe generica e getta per soddisfare il metodo generico nell'interfaccia
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>;
}
}
E infine la chiamata del metodo di interfaccia.
IDatatable<CustomerAccount> table = _database.GetDataTable<CustomerAccount>();
A seguito di domanda ha uno scenario di fusione evitato di usare farmaci generici - [Codice refactoring per evitare Type Casting] (http://stackoverflow.com/questions/21482850/refactoring-code-to-avoid-type-casting) – Lijo