Я не думаю, что вы можете сделать это в качестве одного класса, в настоящее время, как правило, то, что я пытаюсь сделать в этой ситуации является создание наиболее общий класс (тот, который принимает самые общие аргументы), чтобы все логики, затем сделать более конкретными подклассы, которые по умолчанию используют эти типы.
Например, предположим, что мы пишем переводчика, который переводит с одного типа значения к другому, так как у 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
является дополнением (а не что-то дефолте), то как это было сделано Уместно.
Зависит от того, чего вы хотите достичь – Magnus
Я хочу, чтобы TValidator был необязательным. – CaffGeek
Wow ... 3 закрыто голосов? ZERO объяснения. – CaffGeek