Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. LINQ
  4. Invoke MethodExpression

Invoke MethodExpression

Scheduled Pinned Locked Moved LINQ
helptutorialquestion
3 Posts 2 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Adriaan Davel
    wrote on last edited by
    #1

    I'm struggling with a rather elaborate Expression attempt, any help will be appreciated: I have a method: public QueryContext<T> OrderBy(Expression<Func<T, SortColumn>> orderByExpression) that I string onto a number of methods (either the same method or some of my other methods that look similar exposed by QueryContext<T>) in code something like this:

    return this.Get<DataStorageLocation>(dsl => !dsl.Deleted)
    .IncludeReferencedObject(dsl => new RangedColumn<DataStorageLocation>(dsl.ChildLocations)
    .Where<DataStorageLocation>(cdsl => !cdsl.Deleted)
    .Where<DataStorageLocation>(cdsl => cdsl.Deleted == false)
    .Where<DataStorageLocation>(cdsl => cdsl.Id > 0)
    .OrderBy(cdsl => new SortColumn<DataStorageLocation>(cdsl.LocationName)))).ToList();

    (this is not very logical code, but gives a good debuggin example) and produces an expression something like this:

    new RangedColumn`1(dsl.ChildLocations).Where(cdsl => Not(cdsl.Deleted)).Where(cdsl => (cdsl.Deleted = False)).Where(cdsl => (cdsl.Id > 0)).OrderBy(cdsl => new SortColumn`1(cdsl.LocationName))

    Problem comes in when I try to invoke the OrderBy MethodExpression like this:

    var args = (from a in methodCallExpression.Arguments select a as Expression).ToList();
    methodCallExpression.Method.Invoke(column, args.ToArray());

    The Method Name that I have from methodCallExpression.Method.Name is OrderBy and the arguments that I have is cdsl => new SortColumn`1(cdsl.LocationName) which looks correct, yet I get an exception that my expression cannot be cast to 'Expression<Func<T, SortColumn>> orderByExpression' which is my method signature so I almost understand that there is a problem, but what I don't understand is how invoking the method, with the arguments it has for itself gives an error... I've only been playing with Expressions for a (painful) couple of days, if this is a stupid question please answer it before you frag me :) PS: I've tried to write an overload method for OrderBy that takes an Expression object as a parameter, yet the Invoke method insists on calling the other method (which I also understand)

    ____________________________________________________________ Be brave little warrior, be VERY brave

    D 1 Reply Last reply
    0
    • A Adriaan Davel

      I'm struggling with a rather elaborate Expression attempt, any help will be appreciated: I have a method: public QueryContext<T> OrderBy(Expression<Func<T, SortColumn>> orderByExpression) that I string onto a number of methods (either the same method or some of my other methods that look similar exposed by QueryContext<T>) in code something like this:

      return this.Get<DataStorageLocation>(dsl => !dsl.Deleted)
      .IncludeReferencedObject(dsl => new RangedColumn<DataStorageLocation>(dsl.ChildLocations)
      .Where<DataStorageLocation>(cdsl => !cdsl.Deleted)
      .Where<DataStorageLocation>(cdsl => cdsl.Deleted == false)
      .Where<DataStorageLocation>(cdsl => cdsl.Id > 0)
      .OrderBy(cdsl => new SortColumn<DataStorageLocation>(cdsl.LocationName)))).ToList();

      (this is not very logical code, but gives a good debuggin example) and produces an expression something like this:

      new RangedColumn`1(dsl.ChildLocations).Where(cdsl => Not(cdsl.Deleted)).Where(cdsl => (cdsl.Deleted = False)).Where(cdsl => (cdsl.Id > 0)).OrderBy(cdsl => new SortColumn`1(cdsl.LocationName))

      Problem comes in when I try to invoke the OrderBy MethodExpression like this:

      var args = (from a in methodCallExpression.Arguments select a as Expression).ToList();
      methodCallExpression.Method.Invoke(column, args.ToArray());

      The Method Name that I have from methodCallExpression.Method.Name is OrderBy and the arguments that I have is cdsl => new SortColumn`1(cdsl.LocationName) which looks correct, yet I get an exception that my expression cannot be cast to 'Expression<Func<T, SortColumn>> orderByExpression' which is my method signature so I almost understand that there is a problem, but what I don't understand is how invoking the method, with the arguments it has for itself gives an error... I've only been playing with Expressions for a (painful) couple of days, if this is a stupid question please answer it before you frag me :) PS: I've tried to write an overload method for OrderBy that takes an Expression object as a parameter, yet the Invoke method insists on calling the other method (which I also understand)

      ____________________________________________________________ Be brave little warrior, be VERY brave

      D Offline
      D Offline
      Daniel Grunwald
      wrote on last edited by
      #2

      When your expression is 'x.Where(a => f(a))' and the Where method takes an Expression<Func<T>>, then the expression tree actually is:

      MethodCallExpression

      • Object: x
      • Method: Where
      • Arguments:
        • UnaryExpression (Type: Quote)
          • LambdaExpression
            • Parameter: a
            • Body: f(a)

      'Quote' is the operator that converts from a lambda to an expression tree (similar to quote in LISP). So you're trying to call Where with an UnaryExpression where it expects an Expression<Func<T>>. Solution: use Expression.Lambda<TDelegate>() to create a new typed lambda expression reusing the parameter and body from the input LambdaExpression.

      A 1 Reply Last reply
      0
      • D Daniel Grunwald

        When your expression is 'x.Where(a => f(a))' and the Where method takes an Expression<Func<T>>, then the expression tree actually is:

        MethodCallExpression

        • Object: x
        • Method: Where
        • Arguments:
          • UnaryExpression (Type: Quote)
            • LambdaExpression
              • Parameter: a
              • Body: f(a)

        'Quote' is the operator that converts from a lambda to an expression tree (similar to quote in LISP). So you're trying to call Where with an UnaryExpression where it expects an Expression<Func<T>>. Solution: use Expression.Lambda<TDelegate>() to create a new typed lambda expression reusing the parameter and body from the input LambdaExpression.

        A Offline
        A Offline
        Adriaan Davel
        wrote on last edited by
        #3

        Hi Daniel, Thanks, will give this a try

        ____________________________________________________________ Be brave little warrior, be VERY brave

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups