如何执行字符串中的代码?
说我有这样的事情:
string singleStatement = "System.DateTime.Now";
有没有办法在运行时采用singleStatement
并解析并运行它?
以便:
DateTime currentTime = singleStatement.SomeCoolMethodToRunTheText();
将DateTime.Now
的值赋给currentTime
。
阅读本文 (引用如下)。
这是可能的:看看System.CodeDom
和System.CodeDom.Compiler
。
我找到了几个月前写的一个例子:假设usingList
是一个带有所有using语句的arraylist
(不使用关键字,例如System.Xml
)假设importList
是一个arraylist
,其中包含编译所需的所有dll名称( system.dll
for假设source
是要编译的源代码假设classname
是要编译的classname
的名称假设methodname
是方法的名称
看看下面的代码:
//Create method CodeMemberMethod pMethod = new CodeMemberMethod(); pMethod.Name = methodname; pMethod.Attributes = MemberAttributes.Public; pMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string[]),"boxes")); pMethod.ReturnType=new CodeTypeReference(typeof(bool)); pMethod.Statements.Add(new CodeSnippetExpression(@" bool result = true; try { " + source + @" } catch { result = false; } return result; ")); //Crée la classe CodeTypeDeclaration pClass = new System.CodeDom.CodeTypeDeclaration(classname); pClass.Attributes = MemberAttributes.Public; pClass.Members.Add(pMethod); //Crée le namespace CodeNamespace pNamespace = new CodeNamespace("myNameSpace"); pNamespace.Types.Add(pClass); foreach(string sUsing in usingList) pNamespace.Imports.Add(new CodeNamespaceImport(sUsing)); //Create compile unit CodeCompileUnit pUnit = new CodeCompileUnit(); pUnit.Namespaces.Add(pNamespace); //Make compilation parameters CompilerParameters pParams = new CompilerParameters((string[])importList.ToArray(typeof(string))); pParams.GenerateInMemory = true; //Compile CompilerResults pResults = (new CSharpCodeProvider()) .CreateCompiler().CompileAssemblyFromDom(pParams, pUnit); if (pResults.Errors != null && pResults.Errors.Count>0) { foreach(CompilerError pError in pResults.Errors) MessageBox.Show(pError.ToString()); result = pResults.CompiledAssembly.CreateInstance("myNameSp ace."+classname); }
例如,
if 'usingList' equals { "System.Text.RegularExpressions" } if 'importList' equals { "System.dll" } if 'classname' equals "myClass" if 'methodName' equals "myMethod" if 'source' equals " string pays=@"ES FR EN " Regex regex=new Regex(@"^[A-Za-z] { 2 } $"); result=regex.IsMatch(boxes[0]); if (result) { regex=new Regex(@"^"+boxes[0]+@".$",RegexOptions.Multiline); result=regex.Matches(pays).Count!=0; }
然后将编译的代码如下:
using System.Text.RegularExpressions; namespace myNameSpace { public class myClass { public bool myMethod(string[] boxes) { bool result=true; try { string pays=@"ES FR EN " Regex regex=new Regex(@"^[A-Za-z] { 2 } $"); result=regex.IsMatch(boxes[0]); if (result) { regex=new Regex(@"^"+boxes[0]+@".$",RegexOptions.Multiline); result=regex.Matches(pays).Count!=0; } } catch { result=false; } return result; } } }
这只能通过使用编译器服务和Reflection.Emit()
,它将编译和汇编并加载到内存中。
看看这里。
您可以使用CSharpCodeProvider对象在运行时编译代码。 无论你是否真的想要这样做,都需要辩论。 🙂