6

我想采用一个带有变量的数学表达式并打印(分配给字符串)填充了变量的公式。

int iTwo = 2;
int iResult = 0;

iResult = iTwo * iTwo;

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

在上面的代码中 iResult = 4 和 theString = "4"

我想做一些填充变量并返回数学表达式的事情,例如:

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

最后以 theString = "2 * 2";

想法?

4

7 回答 7

5

你可以使用Expression<>类型。

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)

您需要使该方法更复杂才能解析比简单的二进制表达式更复杂的事物,但这是一般的想法。您可以这样做e.Body.ToString(),但是由于为您的 lambda 制作匿名类型的方式,这可能会得到丑陋的结果,例如:"(value(TestApp.Program+<>c__DisplayClass3).iTwo * value(TestApp.Program+<>c__Dis playClass3).iTwo)".

于 2012-07-05T20:30:15.703 回答
1

随着一些运算符重载...

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();
    }
}

当然,您需要以类似的方式重载您需要的其他运算符(例如+/等等)。
如果需要,您还应该提供接受除 int 以外的其他类型的方法,但基本思想保持不变。

请注意,您必须仅将第一个操作数强制转换为 Expression,否则您只会得到要转换的结果。

于 2012-07-05T20:27:10.193 回答
1

您可以使用Expression<>和存储在表达式中的参数信息来获得您想要的。将表达式存储在Expression<>变量中。

int n1 = 4;
int n2 = 3;
Expression<Func<int, int, int>> exp = (arg1, arg2) => arg1 * arg2;

string expString = exp.ToString(); // (arg1, arg2) => arg1 * arg2
int startRHS = expString.IndexOf("=>") + 2; // starting index of RHS
string onlyRHS = expString.Substring(startRHS).Trim();  // arg1 * arg2

// replace args with values
string withValues = onlyRHS.Replace(exp.Parameters[0].Name, n1.ToString()); // 4 * arg2
withValues = withValues.Replace(exp.Parameters[1].Name, n2.ToString()); // 4 * 3

虽然这不是最强大的解决方案,但它适用于简单的场景。

于 2012-07-05T20:46:01.270 回答
0
string ExpressionToString(int first, string operator, int second)
{
   StringBuilder sb = new StringBuilder();
   sb.Append(first.ToString());
   sb.Append(operator);
   sb.Append(second.ToString());
   return sb.ToString();
}
于 2012-07-05T20:05:29.643 回答
0
public static string ExpressionToString(params object[] param)
{
    return string.Join(" ", param.Select(t => t.ToString()).ToArray());
}

使用:

string result = Helper.ExpressionToString(2, "*", 2 , ">=", -10);
//result = "2 * 2 >= -10";
于 2012-07-05T20:07:24.907 回答
-1

您可以创建自己的方法,该方法调用类似于以下内容:

public string ExpressionToString(int parameter1, string operator, int parameter2) {
  return string.Format("{0} {1} {2}", parameter1, operator, parameter2);
}
于 2012-07-05T20:02:31.480 回答
-1

请使用创建您的方法并在其中使用以下代码来满足您的要求

string answer = string.Format("{0} {1} {2} = {3}", iTwo, iTwo, operator, result);
于 2012-07-05T20:04:26.280 回答