Ответ 1
Я не думаю, что вы можете сделать это как один класс, в настоящее время, как правило, то, что я пытаюсь сделать в этой ситуации, - это создать наиболее общий класс (тот, который принимает самые общие аргументы), чтобы иметь всю логику, затем сделайте более конкретными подклассы, которые по умолчанию используют эти типы.
Например, скажем, мы пишем переводчик, который переводит из одного типа значения в другой, так что как Dictionary
, но также имеет значения по умолчанию и т.д.
Мы могли бы определить это как:
public class Translator<TKey, TValue, TDictionary> where TDictionary : IDictionary<TKey, TValue>, new();
{
private IDictionary<TKey, TValue> _map = new TDictionary();
...
}
Это мой общий случай, который может иметь любую реализацию IDictionary
, но, скажем, нам нужна более простая версия, которая всегда использует Dictionary
, если не указано, мы могли бы сделать:
public class Translator<TKey, TValue> : Translator<TKey, TValue, Dictionary<TKey, TValue>>
{
// all this does is pass on the "default" for TDictionary...
}
Таким образом, я могу сделать:
// uses Dictionary<int, string>
var generic = new Translator<int, string>();
// uses SortedDictionary instead
var specific = new Translator<int, string, SortedDictioanry<int, string>>();
Итак, в вашем случае, возможно, ваш родословный всегда имеет свойство TValidator, но он по умолчанию (возможно, всегда возвращать true
в вашей самой общей форме?
Например, возможно, у вас есть определение валидатора по умолчанию (например, называемое DefaultValidator
), вы можете отменить свои определения, чтобы более общий (тот, который принимает более общие параметры типа) имеет всю логику и любые специализации ( меньшее количество параметров) - это просто подклассы, которые по умолчанию используют эти дополнительные типы:
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...
}
}
UPDATE. Да, на основе вашего комментария, если TValidator
является надстройкой (а не чем-то дефолтом), то наложение его, как и вы, было подходящим.