2012-07-05 32 views
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」結束了;

想法?

+0

好想法到目前爲止傢伙,但這裏是併發症...今天的表達可能是:itwo * itwo ...但明天的表達可能是:(itwo * itwo)/ anotherVar ...我需要轉換任何數量的值,然後轉換爲字符串(保留運算符,括號等),換句話說,我將有不同的表達式,需要進行評估並轉換爲字符串 – pStan 2012-07-05 20:13:08

回答

4

您可以使用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)"

+1

這很好,因爲他可以編譯表達式並執行它。 – Gabe 2012-07-05 20:41:23

0

你可以創建自己的方法調用與此類似:

public string ExpressionToString(int parameter1, string operator, int parameter2) { 
    return string.Format("{0} {1} {2}", parameter1, operator, parameter2); 
} 
0

請使用創建你的方法,並在其中使用下面的代碼來實現您的要求

string answer = string.Format("{0} {1} {2} = {3}", iTwo, iTwo, operator, result); 
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(); 
} 
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"; 
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以外的其他類型的方法,但基本思路保持不變。

請注意,您必須只將表達式轉換爲表達式的第一個操作數,否則您只會得到要轉換的結果。

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 

雖然這不是最強大的解決方案,但它適用於簡單的場景。