C#在动态代码中创建一个类的实例不起作用

时间:2018-01-24 09:34:54

标签: c#

我有一个文本框,用户可以在其中输入一些代码并执行它。它创建一个动态类并运行它。在这个类中,我尝试创建另一个类的实例,但编译器找不到它:

执行代码的功能:

private void Execute(string code)
{
    StringBuilder sb = new StringBuilder();

    //-----------------
    // Create the class as usual
    sb.AppendLine("using System;");
    sb.AppendLine("using System.Windows.Forms;");
    sb.AppendLine("using System.Collections.Generic;");
    sb.AppendLine("using System.Linq;");
    sb.AppendLine("using System.Text;");
    sb.AppendLine("using System.Threading.Tasks;");
    sb.AppendLine();
    sb.AppendLine("namespace Testumgebung");
    sb.AppendLine("{");

    sb.AppendLine("      public class UserCodeClass");
    sb.AppendLine("      {");

    sb.AppendLine("            EA_Netzteil NG1 = new EA_Netzteil();");
    sb.AppendLine("            public bool KS1isUsed { get; set; }");
    // Function
    sb.AppendLine("            public string myFunction(int input)");
    sb.AppendLine("            {");
    sb.AppendLine("                 if(KS1isUsed)");
    sb.AppendLine("                 {");

    sb.AppendLine("                 }");
    sb.AppendLine(code);
    sb.AppendLine("            }");
    sb.AppendLine("      }");
    sb.AppendLine("}");


    //-----------------
    // The finished code
    String classCode = sb.ToString();

    //-----------------
    // Dont need any extra assemblies
    Object[] requiredAssemblies = new Object[] { };

    dynamic classRef;
    try
    {
        TextBox_skripte_runlog.Clear();

        //------------
        // Pass the class code, the namespace of the class and the list of extra assemblies needed
        classRef = CodeHelper.HelperFunction(classCode, "Testumgebung.UserCodeClass", requiredAssemblies);

        //-------------------
        // If the compilation process returned an error, then show to the user all errors
        if (classRef is CompilerErrorCollection)
        {
            StringBuilder sberror = new StringBuilder();

            foreach (CompilerError error in (CompilerErrorCollection)classRef)
            {
                sberror.AppendLine(string.Format("{0}:{1} {2} {3}", error.Line, error.Column, error.ErrorNumber, error.ErrorText));
            }

            TextBox_skripte_runlog.Text = sberror.ToString();

            return;
        }
    }
    catch (Exception ex)
    {
        // If something very bad happened then throw it
        MessageBox.Show(ex.Message);
        throw;
    }

    //-------------
    // Finally call the class 
    string targetValues = classRef.myFunction(3);

}

助手类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Reflection.Emit;


namespace Testumgebung
{
    public class CodeHelper
    {
        public static object HelperFunction(String classCode, String mainClass, Object[] requiredAssemblies)
        {
            CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string>
              {
                 { "CompilerVersion", "v4.0" }
              });

            CompilerParameters parameters = new CompilerParameters
            {
                GenerateExecutable = false,       // Create a dll
                GenerateInMemory = true,          // Create it in memory
                WarningLevel = 3,                 // Default warning level
                CompilerOptions = "/optimize",    // Optimize code
                TreatWarningsAsErrors = false     // Better be false to avoid break in warnings
            };


            //----------------
            // Add basic referenced assemblies
            parameters.ReferencedAssemblies.Add("system.dll");
            parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
            parameters.ReferencedAssemblies.Add("System.Core.dll");


            //----------------
            // Add all extra assemblies required
            foreach (var extraAsm in requiredAssemblies)
            {
                parameters.ReferencedAssemblies.Add(extraAsm as string);
            }

            //--------------------
            // Try to compile the code received
            CompilerResults results = provider.CompileAssemblyFromSource(parameters, classCode);

            //--------------------
            // If the compilation returned error, then return the CompilerErrorCollection class 
            // with the errors to the caller
            if (results.Errors.Count != 0)
            {
                return results.Errors;
            }

            //--------------------
            // Return the created class instance to caller
            return results.CompiledAssembly.CreateInstance(mainClass); ;
        }
    }
}

EA_Netzteil课程:

namespace Testumgebung
{
    public class EA_Netzteil
    {
    }
}

问题是EA_Netzteil NG1 =新的EA_Netzteil();不起作用。找不到EA_Netzteil。错误如下:

  

CS0246:找不到类型或命名空间名称“EA_Netzteil”(您是否缺少using指令或程序集引用?)

在真正的班级EA_Netzteil NG1 = new EA_Netzteil();正在运作,但不在动态班级。如何让它工作?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

在您的项目中,始终包含您的根命名空间。 在动态编译的类中,您必须手动添加所有名称空间。

相关问题