1

I have a predicate, that was made from lambda expression after all extension methods were served. For example:

(new List<string>).Where(i => i.Contains("some")).Where(i => i.Contains("second_some"));

"List<>" is only example, there could be my custom data context or object collection. So, I have an "Expression<...>", and it's base type "Expression".

The question is, is there are any code, which could walk the tree of expression, and replace parameter type (in our sample it is "string") with another one specified?

I have already found how to replace parameter type, but it has a conflict when the method somewhere from "Where" extension method has a signature with old parameter type.

Maybe someone has met solution? Thanks.

Oleksii G.
  • 487
  • 5
  • 20
  • It's not clear what you'd want to do in this case... "some" is going to be a string no matter what you do, so what would you do if you were converting to use (say) `int`? – Jon Skeet Jul 07 '10 at 14:16
  • for example, there is not "string" but "IUser" interface, and linq2sql is working with classes to build SQL strings, so it's need a class "User". So, I need to replace IUser to User – Oleksii G. Jul 07 '10 at 14:40
  • Are you looking to build an expression for which you don't know the type at run-time, and want to write a lamba 'template' method? – Steve Mitcham Jul 08 '10 at 22:42
  • almost yes. I have an expression, and need to replace type in it. – Oleksii G. Jul 13 '10 at 14:24
  • http://stackoverflow.com/questions/10570942/translating-expression-tree-from-a-type-to-another-type-with-complex-mappings/10643755#10643755 – Double Down Jul 15 '13 at 16:56

1 Answers1

-1

An expression is an immutable type. To replace parameters (and their type) you sould create a new expression using the body of the original expression, passing the parameters you want to use.

            var resultingIQueryable = ( new List<string> () ).AsQueryable<string>().Where (i => i.Contains ("some")).Where (i => i.Contains ("second_some"));

            // the Queryable.Where is a MethodCallExpression
            var expressionOriginal = resultingIQueryable.Expression as MethodCallExpression;
            // there are multiple where calls, this makes it all a little bit more confusing.
            // The linq tree is built 'backwards'
            // the first parameter of the expression is a MethodCallExpression:
            // {System.Collections.Generic.List`1[System.String].Where(i => i.Contains("some"))}
            // the second parameter:
            // {i => i.Contains("second_some")}
            //
            // disecting the first parameter you will again find 2 parameters:
            // {System.Collections.Generic.List`1[System.String]} 
            // {i => i.Contains("some")}

It is not really a good practice to build expressions using linq (method) syntax and then walk the tree to build a new expression. If i were you i would try to build the expression using Expression.Call & Expression.Lambda & Expression.Paremeter... syntax.

Simon Smeets
  • 581
  • 6
  • 17