【问题标题】:Expression Tree 'Any' on Collection集合上的表达式树“任何”
【发布时间】:2017-11-27 14:23:27
【问题描述】:

我正在尝试确定集合中的任何对象是否将 target 属性设置为 true。我怎样才能做到这一点?到目前为止,这是我所拥有的:

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

【问题讨论】:

  • 是否有可能更多地了解您的集合中的对象 - 例如,您能否让它们实现一个具有您想要检查的属性的接口?
  • 他们都是视图模型,托马斯。该属性应该能够用于任何集合。我接受了马克西姆的建议。谢谢

标签: c# .net asp.net-mvc linq expression-trees


【解决方案1】:

你想动态调用Any方法吗?

我建议这样做:

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

你真的不需要你的Call 表达式。

您的方法内部的完整调用就像(在 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 });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多