I have a method signature like this:

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

Example usage:

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

I want to create a more flexible solution and always ignore a few properties from the type (in this case "Request") identified via reflection

My (not working) solution:

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

Question: I guess the expression must be somehow differently passed to the Without method in order to work? But how?

有帮助吗?

解决方案

The simplest way to make this work is to use dynamic:

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

Since row is already statically typed, the dynamic behavior will be contained to only this statement.

If you didn't want to use dynamic, you would need to use reflection to invoke the Without method with the right type parameters, but I don't see any advantage in doing that (it's more complicated, but it isn't any more type-safe).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top