1

In my interface I have following defined

List<IFoo> GetListOfFoo<T>(Expression<Func<T, bool>> predicate) where T : IFoo;

In my implementation I'll cast the expression in the specific type:

if (typeof(T) == typeof(Foo))
{
    Expression converted = Expression.Convert(predicate.Body, typeof(Foo));
    Expression<Func<Foo, bool>> newPredicate = 
        Expression.Lambda<Func<Foo, bool>>(converted, predicate.Parameters);
}

I try to use my implementation like this:

Expression<Func<Foo, bool>> predicate = c => c.Name == "Myname";
_repository.GetListOfFoo<Foo>(predicate);

I get no compiling errors, but if I use this, I get an Exception that in the ExpressionBody is the bool argument defined.

Where is my problem?

Mario Binder
  • 1,604
  • 4
  • 16
  • 24

3 Answers3

1

Your code doesn't make any sense.

You're creating an Expression.Convert that returns a Foo, then trying to use that as a function that returns a bool.

The Expression.Convert also doesn't make sense; you can't convert a bool to a Foo.

You're probably trying to write

var converted = (Expression<Func<Foo, bool>>) predicate;

As long as T is Foo, this will work fine.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Thanks for your answer. I don't want convert a bool to a Foo, but a Foo in a IFoo, because Foo implements IFoo. In my further Methodbody I work with the interface – Mario Binder May 30 '12 at 16:07
  • In other words, you want to walk the expression tree and replace any reference to the parameter with a cast. You need to write an ExpressionVisitor. – SLaks May 30 '12 at 17:42
0

The parameter's type need to change, not the body of the expression.

Upon invocation from your implementation, you would have to do the conversion.

Also does not make sense why you need this as Foo : IFoo.

leppie
  • 115,091
  • 17
  • 196
  • 297
0

I found a better solution. I don't need to cast the predicate themselves.

public List<IFoo> GetFoos<T>(Expression<Func<T, bool>> predicate) where T : class, IModel 
{
    var result = new List<IFoo>();
    var repository = new Repository<T>();
    result.AddRange(repository.GetEntities(predicate).ToList().ConvertAll(c => (IFoo)c));
    return result;
}
Mario Binder
  • 1,604
  • 4
  • 16
  • 24