Arbre d'expression 'Any' on Collection

.net asp.net-mvc c# expression-trees linq

Question

J'essaie de déterminer si la propriété cible de l'un des objets de la collection est définie sur true. Comment puis-je accomplir cela? Voici ce que j'ai jusqu'à présent:

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.");
    }
}

Réponse acceptée

Vous voulez appeler dynamiquement Any méthode?

Je suggérerais de faire quelque chose comme ça:

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

Vous n'avez pas vraiment besoin de votre expression d' Call .

Un appel complet à l’intérieur de votre méthode ressemblerait à (fonctionne pour moi dans 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 });



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi