How to convert string into System.Linq.Expressions.Expression in C#?

Locked How to convert string into System.Linq.Expressions.Expression in C#?

  • Monday, November 30, 2009 11:44 AM
     
     
    This code is works fine.
    Expression<Func<int, int>> fun = (i => (i + i) * 10 / 5 % 7);            

    But i want to get formula from console. So i do like 
             string formula = "i => (i + i) * 10 / 5 % 7";
             Expression<Func<int, int>> fun = (formula);            
    But i is not working bez, string can not be convert into Expression.
    My question is how can i convert?


All Replies

  • Monday, November 30, 2009 12:09 PM
    Moderator
     
     
    There's no simple way to do this without writing a parser. 

    Use the static methods in the Expression class to start building the expression from the ground up.  This won't be simple, and will probably require a fair amount of recursion. 
    Coding Light - Illuminated Ideas and Algorithms in Software
    Coding Light WikiLinkedInForumsBrowser
  • Monday, November 30, 2009 12:35 PM
     
     
    Hi Thanks for the reply.
    Can you give any sample code.

  • Monday, November 30, 2009 1:35 PM
    Moderator
     
     
    A sample would be too complex for a forum post.  I'd suggest you start reading up on how to write a parser. 

    I posted a sample of how to parse and execute a simple bit of arithmetic here.  It's by no means comprehensive, and your application will be much more complex than this if you need to parse out an expression, but it's a start.  

    Coding Light - Illuminated Ideas and Algorithms in Software
    Coding Light WikiLinkedInForumsBrowser
  • Monday, November 30, 2009 2:01 PM
     
      Has Code
    The parser already exists.

    Dictionary<string, string> providerOptions = new Dictionary<string, string>();
    providerOptions.Add("CompilerVersion", "v3.5");
    CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
    CompilerResults results = provider.CompileAssemblyFromSource(new CompilerParameters(new[] { "System.Core.dll" }),
      @"using System;
        using System.Linq.Expressions;
    
        class foo
        {
            public static Expression<Func<int, int>> bar()
            {
                return (i => (i + i) * 10 / 5 % 7);
            }
        }");
    Expression<Func<int, int>> fun = (Expression<Func<int, int>>)results.CompiledAssembly.GetType("foo").GetMethod("bar").Invoke(null, null);
    
  • Tuesday, December 01, 2009 5:07 AM
     
      Has Code
    Hi,
    This code will works fine only.
    Here you use like get the Expression from the method.
    In that bar() method, you just return the expression.
    there is no convert here.

    But if you try like this it wont work.
    public static Expression<Func<int, int>> bar()
            {
                return (Console.ReadLine());
            }
    I want like this. Bez i read the expression from the console only.
    Let me know any idea.
  • Tuesday, December 01, 2009 9:25 AM
     
     Answered
    Just look at what I wrote. The 10 lines starting at "using" are a string. You can concatenate strings. You can inject into that code whatever you want.

    CompilerResults results = provider.CompileAssemblyFromSource(new CompilerParameters(new[] { "System.Core.dll" }),
      @"using System;
        using System.Linq.Expressions;

        class foo
        {
            public static Expression<Func<int, int>> bar()
            {
                return " + myExpression + ";
            }
        }"
    );

    myExpression can be a variable, a method call like Console.ReadLine, or anything else you can concatenate to a string.

    If you inject directly an input from the user, it could be anything. You should check results.Errors before trying to call the foo.bar() method.
    • Marked As Answer by DP_CHE Thursday, December 03, 2009 11:31 AM
    •  
  • Thursday, December 03, 2009 5:11 AM
     
     
    Hi,
    I try this but still i am getting error in CSharpCodeProvider.
    Can you please give some other sample?

  • Thursday, December 03, 2009 8:33 AM
     
     

    Which error do you get?
    Could you post the code you wrote?

  • Thursday, December 03, 2009 10:14 AM
     
     Answered Has Code
    Louis' code is correct, but perhaps DP_CHE didn't transcribe it correctly.

    Here's a complete program that incorporates it; try pasting this into a console app:

    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using Microsoft.CSharp;
    
    public class DemoProgram
    {
        public static void Main()
        {
            Dictionary<string, string> providerOptions = new Dictionary<string, string>();
            providerOptions.Add("CompilerVersion", "v3.5");
            CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
            
            CompilerResults results = provider.CompileAssemblyFromSource
            (
                new CompilerParameters(new[] { "System.Core.dll" }),
    @"using System;
    using System.Linq.Expressions;
    
    class foo
    {
        public static Expression<Func<int, int>> bar()
        {
            return (i => (i + i) * 10 / 5 % 7);
        }
    }"
            );
    
            Expression<Func<int, int>> expression = (Expression<Func<int, int>>)results.CompiledAssembly.GetType("foo").GetMethod("bar").Invoke(null, null);
            Func<int, int> func = expression.Compile();
    
            Console.WriteLine("func(101) = " + func(101));
        }
    }
    
    • Marked As Answer by DP_CHE Thursday, December 03, 2009 11:31 AM
    •  
  • Thursday, December 03, 2009 11:31 AM
     
     Answered
    Hi Louis, Matthew

    You code is right only.
    But i forget to put namespace Microsoft.CSharp

    Thanks 
    • Marked As Answer by DP_CHE Thursday, December 03, 2009 11:32 AM
    •  
  • Friday, April 15, 2011 5:57 PM
     
     

    Hi,

     

    I know this is for winForms, but is it possible for c# for web?

  • Friday, April 15, 2011 6:04 PM
     
     
    Yes, it is.