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()、ラムダに対して匿名型が作成される方法のために、それは醜い結果を得る可能性があります、例えば:"(value(TestApp.Program+<>c__DisplayClass3).iTwo * value(TestApp.Program+<>c__Dis playClass3).iTwo)"

于 2012-07-05T20:30:15.703 に答える
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 に答える
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 に答える
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 に答える
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 に答える
-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 に答える