首先 我们需要知道 在各种语言里面 都是可以直接计算表达式的
比如(以C#为例)
using System;
public static class Driver
{
public static void Run()
{
Double i = 1+2+3;
Console.WriteLine(\"=\"+ i);
}
}
那么就会在控制台输出1+2+3的值 就是6
所以利用这个就能做一个计算器 把上面的东西编译运行就OK 所以用到反射
下面是代码
using System;using System.CodeDom.Compiler;using System.IO;using System.Reflection;using System.Text;using Microsoft.CSharp;
namespace ExpressionCalculator{ class Program { static void Main(string[] args) { Console.WriteLine("ExpressionCalculator 2012-8-26 By fuis"); Console.WriteLine("Enter a expression and press enter key, or an empty line to exit."); String str = Console.ReadLine(); if (str != String.Empty) { CodeDriver driver = new CodeDriver(); Boolean isError; Console.WriteLine(driver.CompileAndRun(str, out isError)); if (isError) { Console.WriteLine("Some Errors happened."); } Console.WriteLine("Press enter key to exit."); Console.ReadLine(); } }
}
public class CodeDriver : MarshalByRefObject { private string prefix = "using System;" + "public static class Driver" + "{" + " public static void Run()" + " {" + "Double i = ";
private string postfix = ";" + "Console.WriteLine(\"=\"+i);" + " }" + "}";
public string CompileAndRun(String input, out Boolean hasError) { hasError = false; String returnData = null;
CompilerResults results = null; using (var provider = new CSharpCodeProvider()) { var options = new CompilerParameters(); options.GenerateInMemory = true;
var sb = new StringBuilder(); sb.Append(prefix); sb.Append(input); sb.Append(postfix);
results = provider.CompileAssemblyFromSource(options, sb.ToString()); }
if (results.Errors.HasErrors) { hasError = true; var errorMessage = new StringBuilder(); foreach (CompilerError error in results.Errors) { errorMessage.AppendFormat("{0} {1}", error.Line, error.ErrorText); } returnData = errorMessage.ToString(); } else { TextWriter temp = Console.Out; var writer = new StringWriter(); Console.SetOut(writer); Type driverType = results.CompiledAssembly.GetType("Driver");
driverType.InvokeMember("Run", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, null); Console.SetOut(temp);
returnData = writer.ToString(); }
return returnData; } }
}
好吧 我还是放图片 度娘略凌乱
太慢了 传个图片
比如(以C#为例)
using System;
public static class Driver
{
public static void Run()
{
Double i = 1+2+3;
Console.WriteLine(\"=\"+ i);
}
}
那么就会在控制台输出1+2+3的值 就是6
所以利用这个就能做一个计算器 把上面的东西编译运行就OK 所以用到反射
下面是代码
using System;using System.CodeDom.Compiler;using System.IO;using System.Reflection;using System.Text;using Microsoft.CSharp;
namespace ExpressionCalculator{ class Program { static void Main(string[] args) { Console.WriteLine("ExpressionCalculator 2012-8-26 By fuis"); Console.WriteLine("Enter a expression and press enter key, or an empty line to exit."); String str = Console.ReadLine(); if (str != String.Empty) { CodeDriver driver = new CodeDriver(); Boolean isError; Console.WriteLine(driver.CompileAndRun(str, out isError)); if (isError) { Console.WriteLine("Some Errors happened."); } Console.WriteLine("Press enter key to exit."); Console.ReadLine(); } }
}
public class CodeDriver : MarshalByRefObject { private string prefix = "using System;" + "public static class Driver" + "{" + " public static void Run()" + " {" + "Double i = ";
private string postfix = ";" + "Console.WriteLine(\"=\"+i);" + " }" + "}";
public string CompileAndRun(String input, out Boolean hasError) { hasError = false; String returnData = null;
CompilerResults results = null; using (var provider = new CSharpCodeProvider()) { var options = new CompilerParameters(); options.GenerateInMemory = true;
var sb = new StringBuilder(); sb.Append(prefix); sb.Append(input); sb.Append(postfix);
results = provider.CompileAssemblyFromSource(options, sb.ToString()); }
if (results.Errors.HasErrors) { hasError = true; var errorMessage = new StringBuilder(); foreach (CompilerError error in results.Errors) { errorMessage.AppendFormat("{0} {1}", error.Line, error.ErrorText); } returnData = errorMessage.ToString(); } else { TextWriter temp = Console.Out; var writer = new StringWriter(); Console.SetOut(writer); Type driverType = results.CompiledAssembly.GetType("Driver");
driverType.InvokeMember("Run", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, null); Console.SetOut(temp);
returnData = writer.ToString(); }
return returnData; } }
}
好吧 我还是放图片 度娘略凌乱
太慢了 传个图片
