3

How do you convert from Expression<Func<IBar, T>> to Expression<Func<Bar, T>> when Bar implements IBar?

There is the answer to this more generic question:

Convert Expression<Func<T1,bool>> to Expression<Func<T2,bool> dynamically

Is that the best method in this case? Is there not an easier way given that Bar implements IBar?

So, given this contrived example code:

          public class Foo<T>
          {
                 private readonly List<T> _list = new List<T>();

                 public void Add(T item)
                 {
                       _list.Add(item);
                 }

                 public bool AnyFunc(Func<T, bool> predicate)
                 {
                       return _list.Any(predicate);
                 }

                 public bool AnyExpression(Expression<Func<T, bool>> expression)
                 {
                       return _list.AsQueryable().Any(expression);
                 }                    
          }

          public interface IBar
          {
                 string Name { get; }
          }

          public class Bar : IBar
          {
                 public string Name { get; set; }
          }

This demonstrates the problem:

          public class Test()
          {
                 private Foo<Bar> _foobar = new Foo<Bar>(); 

                 public void SomeMethodFunc(Func<IBar, bool> predicate)
                 {
                       // WILL COMPILE AND WORKS, casts from Func<IBar, bool> to Func<Bar, bool>
                       var found = _foobar.AnyFunc(predicate);
                 }

                 public void SomeMethodExpression(Expression<Func<IBar, bool>> expression)
                 {
                       // WON'T COMPILE - Can't cast from Expression<Func<IBar, bool>> to Expression<Func<Bar, bool>>  
                       var found = _foobar.AnyExpression(expression);
                 }
          }

Any ideas how I can accomplish something similar to SomeMethodExpression?

Community
  • 1
  • 1
tikinoa
  • 1,267
  • 2
  • 10
  • 14
  • Have you looked at [AutoMapper](https://github.com/AutoMapper/AutoMapper)? Depending on your use case it's [QueryableExtensions](https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions) namespace may solve your issue. But can't say for sure without seeing how you are using `Func` in a non-contrived example. – Scott Chamberlain Apr 25 '14 at 21:51
  • I don't get the question. Judging by your code it seems you're saying "I do this, and it works. I do this other thing, and it doesn't.". If one method works, why are you concerned about the other? – Lasse V. Karlsen Apr 25 '14 at 22:05
  • @LasseV.Karlsen: the one that works uses delegates, the other uses expression trees. – Wiktor Zychla Apr 25 '14 at 22:08
  • You didn't understand my comment/question. You're saying this: a works, b doesn't. Why can't you use a? – Lasse V. Karlsen Apr 25 '14 at 22:09

1 Answers1

5

Since this case is simple and related to "casting" issues only, there is a shortcut:

public void SomeMethodExpression(Expression<Func<IBar, bool>> expression)
{
    Expression<Func<Bar, bool>> lambda = Expression.Lambda<Func<Bar, bool>>(expression.Body, expression.Parameters);
    var found = _foobar.AnyExpression(lambda);
}
Amir Popovich
  • 29,350
  • 9
  • 53
  • 99