Ответ 1
Это возможно только с помощью служб компилятора и Reflection.Emit()
, которые будут компилироваться, собираться и загружаться в память.
Посмотрите здесь.
Скажем, у меня есть что-то вроде этого:
string singleStatement = "System.DateTime.Now";
Есть ли способ взять singleStatement
и проанализировать и запустить его во время выполнения?
Итак, чтобы:
DateTime currentTime = singleStatement.SomeCoolMethodToRunTheText();
присвоит значение DateTime.Now
currentTime
.
Это возможно только с помощью служб компилятора и Reflection.Emit()
, которые будут компилироваться, собираться и загружаться в память.
Посмотрите здесь.
Прочитайте 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 [email protected]"ES
FR
EN
"
Regex regex=new Regex(@"^[A-Za-z]
{
2
}
$");
result=regex.IsMatch(boxes[0]);
if (result)
{
regex=new Regex(@"^"+boxes[0][email protected]".$",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 [email protected]"ES
FR
EN
"
Regex regex=new Regex(@"^[A-Za-z]
{
2
}
$");
result=regex.IsMatch(boxes[0]);
if (result)
{
regex=new Regex(@"^"+boxes[0][email protected]".$",RegexOptions.Multiline);
result=regex.Matches(pays).Count!=0;
}
}
catch
{
result=false;
}
return result;
}
}
}
Вы можете скомпилировать код во время выполнения, используя объект CSharpCodeProvider. Если вы действительно хотите это сделать или нет, то для обсуждения.: -)