我有一个文本框,用户可以在其中输入一些代码并执行它。它创建一个动态类并运行它。在这个类中,我尝试创建另一个类的实例,但编译器找不到它:
执行代码的功能:
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();
正在运作,但不在动态班级。如何让它工作?
提前感谢您的帮助。
答案 0 :(得分:1)
在您的项目中,始终包含您的根命名空间。 在动态编译的类中,您必须手动添加所有名称空间。