2016-12-23 1 views
0

IList<T>の重複をチェックするバリデーターを作成しました。TKeyを推定できますか?

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var bar = new Foo() {Bar = "buzz"}; 
      var list = new List<Foo>() { }; //Foo has a property named Bar of type string 
      var validator = new Validator<Foo, string>(x => x.Bar); //I have to specify the type of Bar 
      validator.IsValid(list); 
     } 
    } 
} 

public class Foo 
{ 
    public string Bar { get; set; } 
} 

public class Validator<T, Tkey> 
{ 
    private readonly Func<T, Tkey> _keySelector; 

    public Validator(Func<T, Tkey> keySelector) 
    { 
     _keySelector = keySelector; 
    } 

    public bool IsValid(IList<T> list) 
    { 
     if (list != null && list.Count > 0) 
     { 
      if (list.GroupBy(_keySelector).Any(g => g.Count() > 1)) 
      { 
       return false; 
      } 
     } 

     return true; 
    } 
} 

私はどのように使用する必要がありますか:私は建設中にバーの種類を指定する必要があります。

質問はValidatorを初期化するときに何とかTKeyをスキップできますか?どういうわけか推測できますか?

+1

public static class Extensions { public static Validator<T, TKey> GetValidatorFor<T, TKey>(this List<T> list, Func<T, TKey> getter) where T : class { return new Validator<T, TKey>(getter); } } 

、その後、あなたはこのようにそれを使用することができます:ここで

はどのようにあります'ラムダを取らない。 – DavidG

+2

私はこの質問の「重複とマークされました」と完全に同意しません。もう1つの投稿では、コンストラクタで* why *型の推論が不可能であるかどうかが尋ねられます。この質問は別の方法がある場合です。これは拡張メソッドを使用することにより、レコード:)のために、だから、(実際には他の投稿の質問に記載されている)ファクトリメソッド –

+0

にあります: 'パブリック静的クラスSomeStaticClass { \tパブリック静的検証 GetValidator (このIEnumerableをリスト、のFunc keyselector) \t {\t \t戻り新しいバリ(keyselector)。 \t} } '単純に以下を使用できます:' var list = new List (); // Fooには、String型のBarというプロパティがあります。 \t var validator = list.GetValidator(x => x.Bar); //コンパイラはリストからT(Foo)を知っていて、返されたプロパティのTKeyは ' –

答えて

1

個別の静的クラスが必要な汎用拡張メソッドを使用できます。一般的な方法は、それらのパラメータからT型を導き出すことができる。 、あなたのコードがなくてもパラメータなしのコンストラクタと `IsValidのはありません、コンパイルされません開始について

var list = new List<Foo>(); 
var validator = list.GetValidatorFor(x => x.Bar); 
+0

Props to Me。名前は同じですが、ほぼ同じ答えで高速でした。 –

1

拡張子(工場)メソッドを使用してバリデーターを作成できます。コンパイラは型を解決する方法を知っている:

public static class SomeStaticClass 
{ 
    public static Validator<T,TKey> CreateValidator<T,TKey>(this IEnumerable<T> list, Func<T,TKey> keyselector) 
    { 
     return new Validator<T,TKey>(keyselector); 
    } 
} 

は今、バリデータは使用して作成することができます。

var list = new List<Foo>(); //Foo has a property named Bar of type string 
var validator = list.CreateValidator(x => x.Bar); //the compiler can infer T (Foo) through the list and TKey from the returned property inside the lambda 
0

あなたは、一般的なパラメータにcurryingを適用するために、一時的なオブジェクトを使用することができます。

static class Validator 
{ 
    public static ValidatorConstructor<T> Construct<T>() => new ValidatorConstructor<T>(); 
} 

class ValidatorConstructor<T> 
{ 
    public Validator<T, TKey> WithSelector<TKey>(Func<T, TKey> selector) => new Validator<T, TKey>(selector); 
} 

class Validator<T, TKey> 
{ 
    public Validator(Func<T, TKey> selector) 
    { 
    } 
} 

使用法:

Validator<Foo, Bar> e = Validator.Construct<Foo>().WithSelector(x => x.Bar); 
関連する問題