Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print the values of an expression as a string

Tags:

c#

.net

I want to take a math expression that takes variables and print (assign to string) the formula with the variables filled in.

int iTwo = 2;
int iResult = 0;

iResult = iTwo * iTwo;

string theString = (iTwo * iTwo).ToString();

In in the above code iResult = 4 and theString = "4"

I would like to do something that fills in the variables and returns the math expression like:

theString = (iTwo * iTwo).ExpressionToString();    

and end up with theString = "2 * 2";

Thoughts?

like image 901
pStan Avatar asked Jul 05 '12 20:07

pStan


2 Answers

You could use the Expression<> type.

public static string ExpressionToString<T>(Expression<Func<T>> e)
{
    var un = e.Body as BinaryExpression;
    if (un != null)
    {
        var left = un.Left.ToString();
        var leftEnd = left.Split('.').LastOrDefault();
        var right = un.Right.ToString();
        var rightEnd = right.Split('.').LastOrDefault();
        return e.Body.ToString().Replace(left, leftEnd).Replace(right, rightEnd);
    }
    return e.Body.ToString();
}

Console.WriteLine(ExpressionToString(() => iTwo * iTwo));

//prints (iTwo * iTwo)

You'll need to make the method more complex to parse things more complex than a simple binary expression, but that's the general idea. You could just do e.Body.ToString(), but due to the way anonymous types are made for your lambdas, that can get ugly results, e.g.: "(value(TestApp.Program+<>c__DisplayClass3).iTwo * value(TestApp.Program+<>c__Dis playClass3).iTwo)".

like image 117
Tim S. Avatar answered Oct 12 '22 15:10

Tim S.


With some operators overloading...

class Expression {

    string exprStr;

    public static explicit operator Expression(int value) {
        return new Expression() { exprStr = value.ToString() };
    }

    public static Expression operator *(Expression exp, int value) {
        return new Expression() { exprStr = exp.exprStr + " * " + value.ToString() };
    }

    public override string ToString() {
        return exprStr;
    }

}

class Program {
    static void Main() {
        int iTwo = 2;
        string theString = ((Expression)iTwo * iTwo).ToString();
    }
}

You would of course, need to overload the other operators you need in a similar way (e.g. +, / and so on).
You should also provide methods accepting other types than int if you need them, but the basic idea remains the same.

Note that you must cast to Expression only the first operand, otherwise you would get only the result to be converted.

like image 29
Paolo Tedesco Avatar answered Oct 12 '22 13:10

Paolo Tedesco