文字列式の結果を計算する方法はありますか?たとえば
、 amystring = "2*a+32-Math.Sin(6)"
が私が持っている変数であることを動的に知っている場合、動的な解決策があるか、を使用している可能性がありますSystem.Reflection
string mystring = "2*a+32-Math.Sin(6)"`;
decimal result = SomeMethod(mystring,3); // where a = 3 for example
文字列式の結果を計算する方法はありますか?たとえば
、 amystring = "2*a+32-Math.Sin(6)"
が私が持っている変数であることを動的に知っている場合、動的な解決策があるか、を使用している可能性がありますSystem.Reflection
string mystring = "2*a+32-Math.Sin(6)"`;
decimal result = SomeMethod(mystring,3); // where a = 3 for example
javascriptに式を計算させるのはどうですか?
Type scriptType = Type.GetTypeFromCLSID(Guid.Parse("0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC"));
dynamic obj = Activator.CreateInstance(scriptType, false);
obj.Language = "javascript";
var res = obj.Eval("a=3; 2*a+32-Math.sin(6)");
これが完全に機能していることがわかった場合は、お手数をおかけして申し訳ありません。私が欲しかったのは、オンザフライコンパイラだけです。&これが私が得るもの
MessageBox.Show(Eval("5*3-Math.Sin(12) + 25*Math.Pow(3,2)").ToString());
public static object Eval(string sCSCode)
{
CodeDomProvider icc = CodeDomProvider.CreateProvider("C#");
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.xml.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.windows.forms.dll");
cp.ReferencedAssemblies.Add("system.drawing.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("using System.Xml;\n");
sb.Append("using System.Data;\n");
sb.Append("using System.Data.SqlClient;\n");
sb.Append("using System.Windows.Forms;\n");
sb.Append("using System.Drawing;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + sCSCode + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
"Error evaluating cs code", MessageBoxButton.OK,
MessageBoxImage.Error);
return null;
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
System.Reflection.MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
次の方法で Datatable のComputeメソッドを使用できます。SomeMethod
static decimal Somemethod(int val)
{
var result = (decimal)new DataTable().Compute(string.Format("2*{0}+32-{1}", val, Math.Sin(6)), "");
return result;
}
簡単に言えば、次のように呼び出すことができます。
result = Somemethod(3);
あなたが求めていることに対するネイティブサポートはないと思いますが、それを達成する方法はいくつかありますが、どれも完全に簡単ではありませんが、簡単だと思う順序で:
希望する表現サポートを備えた組み込み言語を活用します。たとえば、鉄のルビー: http://ironruby.codeplex.com/
LINQPad はどのようにコードをコンパイルしますか?のように、プログラムから C# コンパイラを使用し ます。.
皮肉のようなもので独自の解析を記述してください: http://irony.codeplex.com/
解析したら、式ツリーを使用して結果を取得できます: http://msdn.microsoft.com/en-us/library/bb397951.aspx
式の評価に使用するメソッドを使用して抽象クラスを作成します。実行時に、そのクラスを継承する新しいクラスを作成します。すぐにコードを共有します。
ここで約束されているように、それを行うためのコードは次のとおりです。
public class BaseClass
{
public BaseClass(){}
public virtual double Eval(double x,double y){return 0;}
}
public class MathExpressionParser
{
private BaseClass Evalulator=null;
public MathExpressionParser(){}
public bool Intialize(string equation)
{
Microsoft.CSharp.CSharpCodeProvider cp=new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.ICodeCompiler comp=cp.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters cpar=new CompilerParameters();
cpar.GenerateInMemory=true;
cpar.GenerateExecutable=false;
cpar.ReferencedAssemblies.Add("system.dll");
cpar.ReferencedAssemblies.Add("EquationsParser.exe"); //Did you see this before;
string sourceCode="using System;"+
"class DrivedEval:EquationsParser.BaseClass" +
"{"+
"public DrivedEval(){}"+
"public override double Eval(double x,double y)"+
"{"+
"return "+ /*Looook here code insertion*/ equation +";"+
"}"+
"}";
//the previouse source code will be compiled now(run time);
CompilerResults result=comp.CompileAssemblyFromSource(cpar,sourceCode);
//If there are error in the code display it for the programmer who enter the equation
string errors="";
foreach(CompilerError rrr in result.Errors)
{
if(rrr.IsWarning)
continue;
errors+="\n"+rrr.ErrorText;
errors+="\n"+rrr.ToString();
}
//You Can show error if there in the sourceCode you just compiled uncomment the following
//MessageBox.Show(errors);
if(result.Errors.Count==0&&result.CompiledAssembly!=null)
{
Type objtype=result.CompiledAssembly.GetType("DrivedEval");
try
{
if(objtype!=null)
{
Evalulator=(BaseClass)Activator.CreateInstance(objtype);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message,"Error in Creation the object");
}
return true;
}
else return false;
}
public double evaluate(double x,double y)
{
if(Evalulator==null)
return 0.0;
return this.Evalulator.Eval(x,y);
}
}
そして、それが機能することを確認するために、次の簡単なテストを行う必要があります。
private void button1_Click(object sender, System.EventArgs e)
{
if(parser.Intialize(textBox1.Text)==false)
{
MessageBox.Show("Check equation");
return;
}
textBox4.Text=(parser.evaluate(double.Parse(textBox2.Text),double.Parse(textBox3.Text))).ToString();
}