我知道有两种方式可以实现,
1.利用正则表达式进行语义分析,这种方式需要考虑的东西太多。
2.利用C#对“动态语言”的支持。也就是说,将654*6+65-27/654整个字符串当做一个string类型参数传入某一方法 然后返回执行后的结果,相信这个应该很适合你,下面是一个类,你直接用以下方法调用即可:
如:
public class ProgramTest
{
static void Main(string[] args)
{
string res = string.Empty;
string error = string.Empty;
res = Evaluator.ReturnRsult("654*6+65-27/654", out error); //这里就是你要传进去的式子,只要是标准的式子便可。
if (!string.IsNullOrEmpty(error))
{
Console.WriteLine(error);
}
else
{
Console.WriteLine("执行结果为:" + res);
}
Console.Read();
}
}
------
下面就是实现功能的类,copy到您的程序中就行,注意引用到的名字空间有:
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Text.RegularExpressions;
------------------------
/// <summary>
/// C#代码执行器,提供动态执行C#代码
/// </summary>
public class Evaluator
{
private static CSharpCodeProvider cCodeProder = null;
private static CompilerParameters compPars = null;
private static CompilerResults compResult = null;
private static Regex rexLastCode = new Regex(@"(print:).+;\s*$", RegexOptions.Compiled | RegexOptions.IgnoreCase); //用于搜索最后一条代码的位置
static Evaluator()
{
cCodeProder = new CSharpCodeProvider();
}
/// <summary>
/// 执行指定的代码
/// </summary>
/// <param name="strCodes"></param>
/// <returns></returns>
private static string Eval(string strCodes, out string strErrText)
{
#region 编译代码
strErrText = InitCompile(ref strCodes);
if (strErrText != null) return null;
try
{
compResult = cCodeProder.CompileAssemblyFromSource(compPars, new string[] { strCodes });
}
catch (NotImplementedException nie)
{
strErrText = nie.Message;
return null;
}
if (compResult.Errors.HasErrors)
{
StringBuilder sbErrs = new StringBuilder(strCodes + System.Environment.NewLine);
sbErrs.Append("您所提供的C#代码中存在语法错误!" + System.Environment.NewLine);
foreach (CompilerError err in compResult.Errors)
{
sbErrs.AppendFormat("{0},{1}" + System.Environment.NewLine, err.ErrorNumber, err.ErrorText);
}
strErrText = sbErrs.ToString();
return null;
}
#endregion
Assembly assembly = compResult.CompiledAssembly;
object prgInsl = assembly.CreateInstance("System._ClassEvaluatorCompiler");
MethodInfo medInfo = prgInsl.GetType().GetMethod("PrintResult");
string strRetn;
try
{
strRetn = medInfo.Invoke(prgInsl, null).ToString();
return strRetn;
}
catch (Exception exMsg)
{
strErrText = exMsg.Message;
return null;
}
}
/// <summary>
/// 预编译代码
/// </summary>
/// <param name="strCodes">待编译的源代码</param>
/// <returns>如果错误则返回错误消息</returns>
private static string InitCompile(ref string strCodes)
{
List<string> lstRefs = new List<string>();//代码字符串中的include引用程序集------未使用
List<string> lstUsings = new List<string>();//代码字符串中的using引用命名空间
#region 分离引用的程序集与命名空间
int point = 0;
string strTemp;
char[] cCodes = strCodes.ToCharArray();
for (int i = 0; i < cCodes.Length; ++i)
{
if (cCodes[i] == '\n' || (cCodes[i] == '\r' && cCodes[i + 1] == '\n'))
{
strTemp = strCodes.Substring(point, i - point);
if (strTemp.TrimStart(new char[] { ' ' }).StartsWith("using "))
{
strTemp = strTemp.Substring(6).Trim();
if (!lstUsings.Contains(strTemp))
{
lstUsings.Add(strTemp);
}
else
{
return "预编译失败,代码中不允许包含重复命名空间导入。" + System.Environment.NewLine + "using " + strTemp;
}
point = cCodes[i] == '\n' ? i + 1 : i + 2;
++i;
}
else if (strTemp.TrimStart(new char[] { ' ' }).StartsWith("include "))
{
strTemp = strTemp.Substring(8).Trim().ToLower();
if (!lstRefs.Contains(strTemp))
{
lstUsings.Add(strTemp);
}
else
{
return "预编译失败,代码中不允许包含重复的程序集引用。" + System.Environment.NewLine + "include " + strTemp;
}
point = cCodes[i] == '\n' ? i + 1 : i + 2;
++i;
}
else
{
break;
}
}
}
strCodes = strCodes.Substring(point);
#endregion
#region 初始化编译参数
if (compPars == null)
{
compPars = new CompilerParameters();
compPars.GenerateExecutable = false;
compPars.GenerateInMemory = true;
}
//string workDir = System.Web.HttpContext.Current.Server.MapPath("~") + "Bin\\";
//string workDir = System.Environment.CurrentDirectory;
compPars.ReferencedAssemblies.Clear();
compPars.ReferencedAssemblies.Add("system.dll");
compPars.ReferencedAssemblies.Add("system.data.dll");
compPars.ReferencedAssemblies.Add("system.xml.dll");
//compPars.ReferencedAssemblies.Add(workDir + "BLL.dll");
//compPars.ReferencedAssemblies.Add(workDir + "Component.dll");
//compPars.ReferencedAssemblies.Add(workDir + "Model.dll");
//compPars.ReferencedAssemblies.Add(workDir + "Utility.dll");
foreach (string str in lstRefs)
{
compPars.ReferencedAssemblies.Add(str);
}
#endregion
StringBuilder sbRetn = new StringBuilder();
#region 生成代码模板
///*为代码添加return 语句*/
Match match = rexLastCode.Match(strCodes);
if (match.Success)
{
strCodes = string.Format("{0}\r\nreturn {1}", strCodes.Substring(0, match.Groups[1].Index), strCodes.Substring(match.Groups[1].Index + match.Groups[1].Length));
}
else
{
strCodes = strCodes.Trim();//把要运行的代码字符串作为返回值---作为输出 - 显示运行的字符串源码
}
/*拼接代码*/
foreach (string str in lstUsings)
{
sbRetn.AppendLine("using " + str);
}
sbRetn.AppendLine("namespace System{");
sbRetn.AppendLine("public class _ClassEvaluatorCompiler{");
sbRetn.AppendLine("public static object PrintResult(){");
sbRetn.AppendLine(strCodes);
sbRetn.AppendLine("}}}");
#endregion
strCodes = sbRetn.ToString();
return null;
}
/// <summary>
/// 执行一段表达式
/// </summary>
/// <param name="info">要执行的表达式字符串</param>
/// <param name="error">错误提示语句</param>
/// <returns>返回执行结果</returns>
public static string ReturnRsult(string info, out string error)
{
string returnStr = string.Empty;
info = "return " + info + ";";
returnStr = Eval(info, out error);
return returnStr;
}
}
温馨提示:内容为网友见解,仅供参考
求一个很基础的c#代码!!万分感谢!!!
2.利用C#对“动态语言”的支持。也就是说,将654*6+65-27\/654整个字符串当做一个string类型参数传入某一方法 然后返回执行后的结果,相信这个应该很适合你,下面是一个类,你直接用以下方法调用即可:如: public class ProgramTest { static void Main(string[] args) { string res = string.Empty; string error...
用C#编写事件:请高手指点一二。。我是自学的。万分感谢!!!
首先A类中要定义事件:【鞭炮声】;然后A类中还要有【触发事件的方法】,所谓触发其实就是调用事件,而事件就是多重委托,调用了事件,就是依次调用了所有绑定到该事件上的委托,而这些委托包含的就是事件的处理方法。要想接到时间通知,那么就要把接收方对象的该事件的处理方法绑定到事件发送方对象的该...
求在ASP.NET中用C#写一个简单的页面计算器!
}2.Calculate.batcsc \/t:library \/out:Calculate.dll Calculate.cs3.执行Calculate.bat4.Calculate.aspx <%@Import NameSpace="Calculate"%> public String color;void DoAdd(Object Src, EventArgs E){ math math=new math();Message.Text=math.Add(Convert.ToInt32(A.Value),Convert.ToInt32(B...
用C#编写一个求解一元二次方程的程序
double x1 = 0;\/\/解1double x2 = 0;\/\/解2Console.WriteLine("求 ax^2+bx+c=0 的解");Console.Write("请输入a的值:");double a = Convert.ToInt32(Console.ReadLine());Console.Write("请输入b的值:");double b = Convert.ToInt32(Console.ReadLine());Console.Write("请输入c的...
...实现碰撞后反弹的那种,能给我发一下吗,万分感谢,601097014@qq.com...
回答:路过。。。
你好,能不能发给我一份用C#求特征值和特征向量的代码?感激不尽啊!
\/\/ 求实对称矩阵特征值与特征向量的雅可比法\/\/\/ 参数:\/\/ 1. double dblEigenValue[] - 一维数组,长度为矩阵的阶数,返回时存放特征值\/\/ 2. CMatrix& mtxEigenVector - 返回时存放特征向量矩阵,其中第i列为与\/\/ 数组dblEigenValue中第j个特征值对应的特征向量\/\/ 3. int nMaxIt - 迭代次数,默认值为60\/...
求C#做计算器的代码,最好能教教我
textBox1.Text=""; textBox1.Focus(); \/\/设置焦点为txtCalc } } } 拿去用好了我试过了能用,新建一个项目名字叫calculator 这个是VS2003版本的,如果你用的是VS2005就直接百度HI我,我把代码发给你,哪里不明白直接教你,就不在这里面发了,我下午一般都在,记得加分哦~ 本回答由提问者推荐 已赞过 已踩过...
C# Winform打印超市小票的代码,在点击收银按钮时,立马自动打印...跪...
Font("Segoe UI", 15, FontStyle.Bold), Brushes.Black, new Point(280, 80));\/\/画从库中取出的数据,txtName1为这个文本框的名字 } \/\/以上给你一小段参考代码:拉一printDocument控件,然后直接画来打印 \/\/然后在前台创建一个btn控件,用以下这个方法就能直接打印了:printDocument1.Print();...
c#.net,望高手指导,送30分
\/\/上面这两段要合在一起看,如果cols里有值,则将Fields以及Values各拼成不同的一句话。例如Fields="(字段1)",如果还有值,再拼成一句话Fields="(字段1,字段2)"Values参照Fields,实现的功能相同 String SqlString = "Insert into "+TableName+Fields+Values;\/\/ 最后就循环拼出一个SQL语句 Sql...
c# 遍历
你给文本框,起一样的名字即可,就是 name 都一样 这样,在 后台 用 Request.Form["name"].Split(',') 获取的,就是一个数组了