locked
Vb 2008 Lambda Expression RRS feed

  • Question

  • Can someone explain to me why I can do this:

     

     Dim expr As Expression(Of Func(Of Object, Object, Object))
     expr = Function(x, y) x + y
     Console.WriteLine(expr.ToString) ---> (x, y) => (x + y)

     

    and this,

     

     Dim expr As Expression(Of Func(Of Object, Object, Object)) = Function(x, y) x + y


    but not this,

     

     Dim expr As Expression(Of Func(Of Object, Object, Object))
     Dim fcn As Func(Of Object, Object, Object) = Function(x, y) x + y
     expr = fcn ---> error 1

     

    Error 1 Value of type 'System.Func(Of Object, Object, Object)' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of Object, Object, Object))'

     

    Incidentally, it is also interesting to note that the string return of the above expr is in terms of C# syntax for a lambda expression.

    ---
    Baxter

    Wednesday, December 26, 2007 6:55 PM

Answers

  • OK, I found the answer by talking to a tester who worked with Expression tree's.  I'm not the expert on this but understood what was occuring.

     

    The way he described it was

    • A Lambda can be converted to an expression tree or a delegate.
    • However a delegate cannot be converted to a expression (or at least that not all delegates)

    He showed me a simple diagram like the following

     

    Lambda  -----> Expression Tree

        |

        |------------> Delegate

     

    So you will see there is no link between Expression Tree and Delegate.

     

    So in your case here - when you do the following.

    Code Block

     

    Dim expr As Expression(Of Func(Of Object, Object, Object))
    expr = Function(x, y) x + y
    Console.WriteLine(expr.ToString) ---> (x, y) => (x + y)

     

     

    Expr is an Expression tree and as the assignment is of the lambda, this is convertible and works just fine.
     

    The 2nd example is doing the same thing but in a single statement.  Declaration and assignment but essentially assigning a lambda to an expression tree.

    Code Block
    Dim expr As Expression(Of Func(Of Object, Object, Object)) = Function(x, y) x + y

     

     

     

    Now in your 3rd example its different, you have specifcally assigned fcn to be of type Func(of Object, Object, Object) and assigned it using a lambda expression.   

     

    Code Block
     Dim expr As Expression(Of Func(Of Object, Object, Object))
     Dim fcn As Func(Of Object, Object, Object) = Function(x, y) x + y
     expr = fcn ---> error 1

     

     

    So in this example you are assigning a lambda expression to a generic delegate type variable (which is acceptable and valid).   Howver you are then trying to assign the variable of generic delegate type to an expression tree (which is not acceptable and valid).  

     

    Hence its different from the above two scenarios.  You trying to do the line between the types which doesnt exist in the diagram.


     

     

    Just to show a 4th example

     

    Code Block

    Dim x1 = Function(x, y) x + y

    Dim expr As Expression(Of Func(Of Object, Object, Object))

    expr = x1

     

     

    Look at the types of x1 as <Function (of Object, Object) as Object>,  Notice the type inference and the < > .  Where have we seen the <> before in type names - anonymous types.    This is a synthesized type name for a anonymous delegate displayed in the IDE that have been infered.  So its still a delegate type and as we have seen we cant assign a delegate to an expression from your 3rd example.   So even use inference this is till not possible and again the line will fail with the error.    The error message refers to the Lambda expression as anonymous method.

     

    Error 2 Value of type '<anonymous method> (line 7)' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of Object, Object, Object))

     

    So hopefully that will explain whats different about the two examples and why they are different and verifies that the assignment of delegates to expression tree doesnt work even in type infered scenarios.

     

    Saturday, December 29, 2007 1:40 AM

All replies

  • How about providing the parameters to the lambda

     

    ie. 

     

    expr = fcn(1, 2)

     

     

    Wednesday, December 26, 2007 10:14 PM
  • Thanks for your answer. expr = fcn(1,2) eliminates the syntax error.

     

    Dim expr As Expression(Of Func(Of Object, Object, Object))
    Dim fcn As Func(Of Object, Object, Object) = Function(x, y) x + y
    expr = fcn(1,2) ---> no error

    Console.WriteLine(expr.ToString)

     

    But,

     

    expr = fcn(1,2) and

    dim x=1Big Smileim y=2: expr = fcn(x,y)

     

    both produce a runtime error,

    Unable to cast object of type 'System.Int32' to type 'System.Linq.Expressions.Expression`1[System.Func`3[System.Object,System.Object,System.Object]]'.

    ---
    Baxter

    Thursday, December 27, 2007 11:01 PM
  • OK, I found the answer by talking to a tester who worked with Expression tree's.  I'm not the expert on this but understood what was occuring.

     

    The way he described it was

    • A Lambda can be converted to an expression tree or a delegate.
    • However a delegate cannot be converted to a expression (or at least that not all delegates)

    He showed me a simple diagram like the following

     

    Lambda  -----> Expression Tree

        |

        |------------> Delegate

     

    So you will see there is no link between Expression Tree and Delegate.

     

    So in your case here - when you do the following.

    Code Block

     

    Dim expr As Expression(Of Func(Of Object, Object, Object))
    expr = Function(x, y) x + y
    Console.WriteLine(expr.ToString) ---> (x, y) => (x + y)

     

     

    Expr is an Expression tree and as the assignment is of the lambda, this is convertible and works just fine.
     

    The 2nd example is doing the same thing but in a single statement.  Declaration and assignment but essentially assigning a lambda to an expression tree.

    Code Block
    Dim expr As Expression(Of Func(Of Object, Object, Object)) = Function(x, y) x + y

     

     

     

    Now in your 3rd example its different, you have specifcally assigned fcn to be of type Func(of Object, Object, Object) and assigned it using a lambda expression.   

     

    Code Block
     Dim expr As Expression(Of Func(Of Object, Object, Object))
     Dim fcn As Func(Of Object, Object, Object) = Function(x, y) x + y
     expr = fcn ---> error 1

     

     

    So in this example you are assigning a lambda expression to a generic delegate type variable (which is acceptable and valid).   Howver you are then trying to assign the variable of generic delegate type to an expression tree (which is not acceptable and valid).  

     

    Hence its different from the above two scenarios.  You trying to do the line between the types which doesnt exist in the diagram.


     

     

    Just to show a 4th example

     

    Code Block

    Dim x1 = Function(x, y) x + y

    Dim expr As Expression(Of Func(Of Object, Object, Object))

    expr = x1

     

     

    Look at the types of x1 as <Function (of Object, Object) as Object>,  Notice the type inference and the < > .  Where have we seen the <> before in type names - anonymous types.    This is a synthesized type name for a anonymous delegate displayed in the IDE that have been infered.  So its still a delegate type and as we have seen we cant assign a delegate to an expression from your 3rd example.   So even use inference this is till not possible and again the line will fail with the error.    The error message refers to the Lambda expression as anonymous method.

     

    Error 2 Value of type '<anonymous method> (line 7)' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of Object, Object, Object))

     

    So hopefully that will explain whats different about the two examples and why they are different and verifies that the assignment of delegates to expression tree doesnt work even in type infered scenarios.

     

    Saturday, December 29, 2007 1:40 AM
  •  

    Thanks for your detailed answer spotty.

     

    ---

    Baxter

    Saturday, December 29, 2007 2:37 AM
  • When I spoke the the chap that tested expression tree's the description he gave was very interesting, its nice to see people are looking at some of the new 2008 features.

     

     

    Saturday, December 29, 2007 3:27 AM