Is there a way I can dynamically define a Predicate body from a string containing the code?

情到浓时终转凉″ 提交于 2019-12-04 13:48:26

The C# and VB compilers are available from within the .NET Framework:

C# CodeDom Provider

Be aware though, that this way you end up with a separate assembly (which can only be unloaded if it's in a separate AppDomain). This approach is only feasible if you can compile all the predicates you are going to need at once. Otherwise there is too much overhead involved.

System.Reflection.Emit is a great API for dynamically emitting code for the CLR. It is, however, a bit cumbersome to use and you must learn CIL.

LINQ expression trees are an easy to use back-end (compilation to CIL) but you would have to write your own parser.

I suggest you have a look at one of the "dynamic languages" that run on the CLR (or DLR) such as IronPython. It's the most efficient way to implement this feature, if you ask me.

TFD

Check out the Dynamic Linq project it does all this and more!

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Great for simple stuff like user selected orderby's or where clauses

Michael Meadows

It is possible using emit, but you'd be building your own parser.

EDIT

I remember that in ScottGu's PDC keynote, he showed a feature using the CLI version of the .net framework that resembled Ruby's eval, but I can't find a URL that can corroborate this. I'm making this a commnity wiki so that anyone who has a good link can add it.

I stepped off the dynamic linq because it's limited in ways I want to search a collection, unless you prove me wrong.

My filter needs to be: in a list of orders, filter the list so that I have only the orders with in the collection of items in that order, an item with the name "coca cola".

So that will result to a method of: orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"))

In dynamic linq I didn't find any way to do that, so I started with CodeDomProvicer. I created a new Type with a method which contains my dynamically built FindAll Method:

public static IList Filter(list, searchString)
{
   // this will by dynamically built code
   return orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"));
}

when I try to build this assembly:

CompilerResults results = provider.CompileAssemblyFromSource(parameters, sb.ToString());

I'm getting the error:

Invalid expression term ">"

Why isn't the compiler able to compile the predicate?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!