C#怎么将字符串类型的表达式计算出来
比如doubleN=1,n=1;strings=“(36*N+2*n)*0.1"表达式是保存在字符串s中的,而且是可以改变的。(用户输入)怎么随着公式的改变,把结果智能的...
比如
double N=1,n=1;
string s=“(36*N+2*n)*0.1"
表达式是保存在字符串s中的,而且是可以改变的。(用户输入)
怎么随着公式的改变,把结果智能的计算出来。
此公式为用户自定义的,保存在xml中,从中读取出来后为字符串类型的,用户在界面输入两个变量(此例为N和n),我需要实现计算功能,根据读取的公式求出结果。请高手指教@@ 展开
double N=1,n=1;
string s=“(36*N+2*n)*0.1"
表达式是保存在字符串s中的,而且是可以改变的。(用户输入)
怎么随着公式的改变,把结果智能的计算出来。
此公式为用户自定义的,保存在xml中,从中读取出来后为字符串类型的,用户在界面输入两个变量(此例为N和n),我需要实现计算功能,根据读取的公式求出结果。请高手指教@@ 展开
6个回答
展开全部
public double Calculate(string formula, double x, double y)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameter = new CompilerParameters();
parameter.ReferencedAssemblies.Add("System.dll");
parameter.GenerateExecutable = false; //<--不生成exe
parameter.GenerateInMemory = true; //<--直接在内存运行
CompilerResults result = provider.CompileAssemblyFromSource(parameter,
GenerateCodeBlocks(formula));
//动态编译(VisualStudio F5的时候也是做这个)
if (result.Errors.Count > 0)
{
MessageBox.Show("error");
}
//编译成功
double calculated = Convert.ToDouble(result.CompiledAssembly.GetType("demo.calculation").GetMethod("dowork").Invoke(null, new object[] { x, y }));
//这里通过反射调
return calculated;
}
string GenerateCodeBlocks(string formula)
{
string code =
"using System;" +
"namespace demo" +
"{" +
"public static class calculation" +
"{" +
"public static double dowork(double x, double y)" +
"{ return " + formula +
";}}}"; //这里是将你的formula和代码片段拼接成完整的程序准备编译的过程。
return code;
}
玩的开心 :)
ps 这动态编译代码我发了好几次了。。问题都差不多啊。。
formula那里带入你的s即可。
如果你还有更多参数可以修改下半部分的代码。
理解为:你动态编译一段C#给你算
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameter = new CompilerParameters();
parameter.ReferencedAssemblies.Add("System.dll");
parameter.GenerateExecutable = false; //<--不生成exe
parameter.GenerateInMemory = true; //<--直接在内存运行
CompilerResults result = provider.CompileAssemblyFromSource(parameter,
GenerateCodeBlocks(formula));
//动态编译(VisualStudio F5的时候也是做这个)
if (result.Errors.Count > 0)
{
MessageBox.Show("error");
}
//编译成功
double calculated = Convert.ToDouble(result.CompiledAssembly.GetType("demo.calculation").GetMethod("dowork").Invoke(null, new object[] { x, y }));
//这里通过反射调
return calculated;
}
string GenerateCodeBlocks(string formula)
{
string code =
"using System;" +
"namespace demo" +
"{" +
"public static class calculation" +
"{" +
"public static double dowork(double x, double y)" +
"{ return " + formula +
";}}}"; //这里是将你的formula和代码片段拼接成完整的程序准备编译的过程。
return code;
}
玩的开心 :)
ps 这动态编译代码我发了好几次了。。问题都差不多啊。。
formula那里带入你的s即可。
如果你还有更多参数可以修改下半部分的代码。
理解为:你动态编译一段C#给你算
追问
不理解这段代码,能不能解释下啊。注释说明详细点,麻烦你了。
追答
嗯,简单的说呢上面代码干的事情就是编译器干的事情。你想:
我写
public class myclass
{
public double calculation(double x, double y)
{
return x+y;
}
}
的话你看得懂吧,
如果我们让x+y这句代码能在运行的时候被动态生成出来,不就达到你说的解释表达式的目的了么(系统来解释而不是你手动)。于是我们就在GenerateCodeBlocks这个函数里用String拼接成一段完整的程序代码,
using System;
namespace demo
{
public static class calculation
{
public static double dowork(double x,double y)
{
return 你的表达式;
}
}
}
然后用上面的那些代码将其动态编译成DLL,实际上你就可以调用了,这样做你可以把表达式或者任何C#代码动态运行出来(软执行)让系统帮你运算,就好像你有一个可以变化代码的类库,根据你的需求生成新的函数供你使用一样。
上面的Reflection那里是你如何调用动态生成的DLL的方法(反射)
result.CompiledAssembly.GetType("demo.calculation").GetMethod("dowork").Invoke(null, new object[] { x, y })
我们分开看,
result.CompiledAssembly是Assembly类型的属性,代表程序集。你当前的程序也是Assembly。
GetType就是通过全名获得Type定义,你可以看到demo.calculation是我们动态生成的dll中对类全名的命名。
GetMethod就是通过这个类的Type+方法名称获得反射到的方法,Invoke就是调用。
第一个null是因为我们是静态类,不需要实例来调用。如果需要实例你就要Type.CreateInstance来创建一个类的实例,然后在这里传入。
第二个new object[]{ }中包含你函数需要的参数,按顺序传入即可。我们定义的时候是double x,double y所以 new object[]{x的值, y的值}
这样完成表达式->包含表达式的程序片段(dll)->动态调用这个片段来运算
可以节省你分析表达式的相关逻辑,交给已经比较成熟的CLR运算库去做
展开全部
首先 你写的是不对哦 字符串数据类型不能进行计算的 你可以这样写
double N=1,n=1;
double num1 = (36*N+2*n)*0.1 ;
string s= num1.ToString();//将小数型转换为字符串
//比如你使用了textBox控件 我们将计算的结果显示到这个控件中
this.textBox1.text = this.s;//将数据显示到控件上
double N=1,n=1;
double num1 = (36*N+2*n)*0.1 ;
string s= num1.ToString();//将小数型转换为字符串
//比如你使用了textBox控件 我们将计算的结果显示到这个控件中
this.textBox1.text = this.s;//将数据显示到控件上
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
public static int jishuan(int N,int n)
{
string s =convert.tostring((36*N+2*n)*0.1);
return s;
}
然后调用的时候 s = jisuan(2,3);//里面参数随便改 但是注意N 和n的顺序一定要对应
就是这个样子 注意有些单词的大小写 我没用编辑器 所以大小写不一定对
{
string s =convert.tostring((36*N+2*n)*0.1);
return s;
}
然后调用的时候 s = jisuan(2,3);//里面参数随便改 但是注意N 和n的顺序一定要对应
就是这个样子 注意有些单词的大小写 我没用编辑器 所以大小写不一定对
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
string s="(36*N+2*n)*0.1";这个是s字符串
把字符串内的字符全部转换类型
double temp=(convert.Todouble(36)*N+couvert.Todouble(2)*n))*counert.todouble(0.1);
把字符串内的字符全部转换类型
double temp=(convert.Todouble(36)*N+couvert.Todouble(2)*n))*counert.todouble(0.1);
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你可以将字符串根据运算符号分解为子字符串,比如根据* ( ) + 等,将数据字符串转换为数字,然后就算即可吧,只是自己的一家之言。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询