从反射类型创建表达式

时间:2014-02-12 10:01:30

标签: c# .net reflection expression expression-trees

我有这样的方法签名:

IPostprocessComposer<T> Without<TProperty>(Expression<Func<T, TProperty>> propertyPicker)

使用示例:

AutoFixture.Build<Request>()
                            .Without(p => p.ID)
                            .Create();

我想创建一个更灵活的解决方案,并始终忽略通过反射识别的类型(在本例中为“请求”)中的一些属性

我的(不工作)解决方案:

IPostprocessComposer<T> row = fixture.Build<T>();

var primitivePropertiesToIgnore = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
    .Where(p => p.Name.ToLowerInvariant().StartsWith("id") || p.Name.ToLowerInvariant().EndsWith("id"));

foreach (var primitiveProperty in primitivePropertiesToIgnore)
{
    var x = Expression.Parameter(typeof(T));
    var expr = Expression.Lambda(Expression.PropertyOrField(x, primitiveProperty.Name), x);

    // This line is working, but of course I need "int" to be a generic type here... how can i achieve this?
    row = row.Without((Expression<Func<T, int>>)expr);
}

问题: 我想表达式必须以某种方式不同地传递给Without方法才能工作?但是如何?

1 个答案:

答案 0 :(得分:2)

最简单的方法是使用dynamic

row = row.Without((dynamic)expr);

由于row已经静态类型化,因此动态行为将仅包含在此语句中。

如果您不想使用dynamic,则需要使用反射来调用具有正确类型参数的Without方法,但我认为这样做没有任何优势(它更复杂,但它不再是类型安全的。)