2012-08-16 13 views
14

これを書くには良い方法はありますか?おそらく2つではなく1つのクラスとして。オプションの汎用タイプ

using System; 

namespace SnippetTool.Repositories 
{ 
    public abstract class ARepository<TProvider> where TProvider : class 
    { 
     protected TProvider Provider { get; set; } 

     protected ARepository(TProvider provider) 
     { 
      if (provider == null) 
       throw new ArgumentNullException("provider"); 

      Provider = provider; 
     } 
    } 

    public abstract class ARepository<TProvider, TValidator> : ARepository<TProvider> where TProvider : class where TValidator : class 
    { 
     protected TValidator Validator { get; set; } 

     protected ARepository(TProvider provider, TValidator validator) : base(provider) 
     { 
      Validator = validator; 
     } 
    } 
} 
+4

達成したいことによります。 – Magnus

+0

私はTValidatorをオプションにしたいと考えています。 – CaffGeek

+1

うわー... 3近い票?ゼロの説明。 – CaffGeek

答えて

11

私は一般的に私がこのような状況で実行しようとすると、すべてを持っている最も一般的なクラス(最も一般的な引数を取る1)を作成され、現在、あなたは一つのクラスとしてそれを行うことができるとは思いませんロジックを作成し、より具体的なものをデフォルトのサブクラスにします。

public class Translator<TKey, TValue, TDictionary> where TDictionary : IDictionary<TKey, TValue>, new(); 
{ 
    private IDictionary<TKey, TValue> _map = new TDictionary(); 
    ... 
} 

たとえば、私たちは、これを定義することができますのは、私たちはなど、

をそうDictionaryのように、別の値のいずれかのタイプから変換トランスレータを書くだけでなく、デフォルト値を持っているとしましょう

これは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を返すために(デフォルト設定ですか?

より一般的な(より一般的なタイプのパラメータを受け取り1)は、すべてのロジックとあらゆる専門分野を持っているように、たとえば、多分あなたは(DefaultValidatorと呼ばれると言う)デフォルトバリデータの定義を持っているあなたは、あなたの定義を逆転できますTValidatorアドオン(をデフォルト設定ない何か)であれば、その後、はい、あなたのコメントに基づいて:

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:(少数の型パラメータ)は、それらの余分なタイプをデフォルトちょうどサブクラスですあなたのようにそれを重ねる適切である。

+0

問題は、私はTValidatorを全く望んでいない場合があります。デフォルトではありません。私はそれを望んでいません。しかし、私はいつもTProviderが必要です。 – CaffGeek

+1

@Chad:あなたのコードはそれを行う良い方法ですが、私の唯一のアドバイスは、重複したロジックを避けるためにクラスをできるだけ軽くしようとすることです。 –

+0

ありがとう、それは私が思ったことを確認します。 – CaffGeek

関連する問題