No creo que lo puede hacer como una clase, en la actualidad, por lo general lo que trato de hacer en esta situación es crear la clase más general (la que lleva los argumentos más genéricos) para tener toda la lógica, luego haga que las más específicas sean subclases que predeterminan esos tipos.
Por ejemplo, digamos que estamos escribiendo un traductor que traduce de un tipo de valor a otro, así como un Dictionary
pero también tiene valores por defecto, etc.
Podríamos definir esto como:
public class Translator<TKey, TValue, TDictionary> where TDictionary : IDictionary<TKey, TValue>, new();
{
private IDictionary<TKey, TValue> _map = new TDictionary();
...
}
Ésta es mi caso genérico, que puede tener cualquier implementación de IDictionary
, pero decir que queremos una versión más sencilla que siempre utiliza Dictionary
si no se especifica, podríamos hacer:
public class Translator<TKey, TValue> : Translator<TKey, TValue, Dictionary<TKey, TValue>>
{
// all this does is pass on the "default" for TDictionary...
}
De esta manera, puedo hacer:
// uses Dictionary<int, string>
var generic = new Translator<int, string>();
// uses SortedDictionary instead
var specific = new Translator<int, string, SortedDictioanry<int, string>>();
Así, en su caso, tal vez su genérico siempre tiene una propiedad TValidator, pero ha de pagar (tal vez para siempre volver true
en su forma más genérica?
Por ejemplo, tal vez usted tiene una definición de un defecto validador (digamos llamada DefaultValidator
) se podría revertir sus definiciones para que el más genérico (la que tiene parámetros de tipo más genérico) tiene toda la lógica y las especializaciones (menor número de parámetros de tipo) son sólo subclases que incumplen esos tipos adicionales:
using System;
namespace SnippetTool.Repositories
{
public class DefaultValidator
{
// whatever your "default" validation is, may just return true...
}
public abstract class ARepository<TProvider> : ARepository<TProvider, DefaultValidator>
where TProvider : class
{
protected ARepository(TProvider provider) : base(provider, new DefaultValidator());
{
}
// needs no new logic, just any specialized constructors...
}
public abstract class ARepository<TProvider, TValidator>
where TProvider : class
where TValidator : class
{
public TValidator Validator { get; set; }
protected ARepository(TProvider provider, TValidator validator)
{
Provider = provider;
Validator = validator;
}
// all the logic goes here...
}
}
ACTUALIZACIÓN: Sí, en base a su comentario, si el TValidator
es un add-on (y no algo defecto), entonces superponiéndolo como lo hiciste es apropiado.
Depende de lo que quiere lograr – Magnus
Quiero lograr que el TValidator sea opcional. – CaffGeek
Wow ... 3 votos cercanos? CERO explicaciones. – CaffGeek