Преобразование выражений Linq - PullRequest
3 голосов
/ 10 января 2011

Я не уверен, как именно аргумент, что я пытаюсь достичь, поэтому - написал код:

public class Foo{
 public Bar Bar{get;set;}
}

public class Bar{
 public string Fizz{get;set;}
}

public class Facts{
 [Fact]
 public void fact(){
   Assert.Equal(expectedExp(),barToFoo(barExp()));
 }
 private Expression<Func<Foo,bool>> expectedExp(){
   return f=>f.Bar.Fizz=="fizz";
 }
 private Expression<Func<Bar,bool>> barExp(){
   return b=>b.Fizz=="fizz";
 }
 private Expression<Func<Foo,bool>> barToFoo
  (Expression<Func<Bar,bool>> barExp){
   return Voodoo(barExp); //<-------------------------------------------???
 }          
}

Возможно ли это вообще?

1 Ответ

2 голосов
/ 10 января 2011
public class Foo
{
    public Bar Bar { get; set; }
}

public class Bar
{
    public string Fizz { get; set; }
}

private Expression<Func<Bar, bool>> BarExp()
{
    return b => b.Fizz == "fizz";
}

private Expression<Func<Foo, bool>> BarToFoo(Expression<Func<Bar, bool>> barExp)
{
    Expression<Func<Foo, Bar>> barMemberAccessExpression = foo => foo.Bar;

    var fooParam = Expression.Parameter(typeof(Foo), "foo");

    var invokeExpression = Expression.Invoke(
        barExp,
        Expression.Invoke(barMemberAccessExpression, fooParam)
        );

    var result = Expression.Lambda<Func<Foo, bool>>(invokeExpression, fooParam);

    return result;

    //Expression<Func<Foo, bool>> result =
    //    foo => barExp.Compile().Invoke(foo.Bar);

    //return result;
}

[Test]
public void TestBarToFoo()
{
    var fooInstance = new Foo { Bar = new Bar() { Fizz = "fizz" } };

    var barExpr = this.BarExp();

    Console.WriteLine(
        barExpr.Compile().Invoke(fooInstance.Bar)); // = True

    Console.WriteLine(
        this.BarToFoo(barExpr).Compile().Invoke(fooInstance)); // = True
}
...