2017-11-27 1 views
2

コレクション内のオブジェクトにtargetプロパティがtrueに設定されているかどうかを確認しようとしています。どうすればこれを達成できますか?コレクション上の表現ツリー 'Any'

public class AnyValidAttribute : ValidationAttribute 
{ 
    private static MethodInfo AnyMethod = 
     typeof(Enumerable) 
      .GetMethods() 
      .First(m => m.Name == "Any" && m.GetParameters().Length == 2)); 

    string booleanPropertyToCheck; 
    Type entityType; 

    public AnyValidAttribute(string booleanPropertyToCheck, Type entityType) 
    { 
     this.booleanPropertyToCheck = booleanPropertyToCheck; 
     this.entityType = entityType; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var collection = new List<object>((IEnumerable<object>)value); 
     var propInfo = this.entityType.GetProperty(this.booleanPropertyToCheck); 
     var param = Expression.Parameter(this.entityType, "entity"); 
     var property = Expression.MakeMemberAccess(param, propInfo); 
     var trueValue = Expression.Constant(true); 
     var comparison = Expression.Equal(property, trueValue); 
     var lambda = Expression.Lambda(comparison, param); 
     var call = Expression.Call(AnyMethod, comparison, lambda); 
     var anyTrue = ??? 

     return true ? null : new ValidationResult("At least one is required."); 
    } 
} 
+0

はそれが可能あなたのコレクション内のオブジェクトについての詳細を知ることです - あなたは、例えば、それらを実装することができます確認したいプロパティを持つインターフェイス? –

+0

これはすべてのビューモデル、Tomasです。属性は、任意のコレクションで使用できる必要があります。私はマクシムの提案に行った。ありがとうございました – end1dream

答えて

2

はあなたが動的にAnyメソッドを呼び出したい:ここでは、私がこれまでしている何ですか?

私はこのようなsomehtingを行うことを示唆している:あなたは本当にあなたのCall式を必要としない

var anyDelegate = lambda.Compile(); 
var genericMethod = AnyMethod.MakeGenericMethod(entityType); 
var anyTrue = (bool)genericMethod.Invoke(null, new[] {value, genericMethod}); 

。 (Linqpadに私の作品)のようなあなたのメソッドの内部

完全な呼び出しは次のようになります。

var propInfo = this.entityType.GetProperty(this.booleanPropertyToCheck); 

var param = Expression.Parameter(this.entityType, "entity"); 
var property = Expression.MakeMemberAccess(param, propInfo); 
var trueValue = Expression.Constant(true); 
var comparison = Expression.Equal(property, trueValue); 
var lambda = Expression.Lambda(comparison, param); 

var anyDelegate = lambda.Compile(); 

var genericMethod = AnyMethod.MakeGenericMethod(entityType); 
var anyTrue = (bool)genericMethod.Invoke(null, new[] { value, anyDelegate }); 
関連する問題