私はあなたが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...
}
}
更新:はい、あなたのコメントに基づいて、TValidator
がアドオンである場合(デフォルトのものではない場合)、あなたがしたようにそれをレイヤー化することが適切です。