Как выполнить код, который находится в строке?

Скажем, у меня есть что-то вроде этого:

string singleStatement = "System.DateTime.Now";

Есть ли способ взять singleStatement и проанализировать и запустить его во время выполнения?

Итак, чтобы:

DateTime currentTime = singleStatement.SomeCoolMethodToRunTheText();

присвоит значение DateTime.Now currentTime.

Ответ 1

Это возможно только с помощью служб компилятора и Reflection.Emit(), которые будут компилироваться, собираться и загружаться в память.

Посмотрите здесь.

http://www.c-sharpcorner.com/UploadFile/puranindia/419/

Ответ 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 [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;
        }
    }
}

Ответ 3

Вы можете скомпилировать код во время выполнения, используя объект CSharpCodeProvider. Если вы действительно хотите это сделать или нет, то для обсуждения.: -)