说我有这样的事情:
string singleStatement = "System.DateTime.Now";
有没有办法在运行时使用singleStatement
并解析并运行它?
那样:
DateTime currentTime = singleStatement.SomeCoolMethodToRunTheText();
会将DateTime.Now
的值分配给currentTime
。
答案 0 :(得分:2)
阅读this(引用如下)。
这是可能的:看看System.CodeDom
和System.CodeDom.Compiler
。
我找到了几个月前写的一个例子:
假设usingList
是一个arraylist
,其中包含所有使用语句(不使用
关键字,例如System.Xml
)
假设importList
是arraylist
,其中包含所有必需的dll名称
编译(例如system.dll
)
假设source
是您要编译的源代码
假设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;
}
}
}
答案 1 :(得分:1)
这只能通过使用编译器服务和Reflection.Emit()
来实现,它将编译和汇编并加载到内存中。
看看这里。
答案 2 :(得分:-1)
您可以使用CSharpCodeProvider对象在运行时编译代码。你是否真的想要这样做是有争议的。 : - )