如何在 C# 中从 CodeDom return 自定义 class?
How to return a custom class from CodeDom in C#?
我想从 Codedom 创建的函数中 return 自定义 class(例如 User
)。我的 User
class 在另一个 class 库中,与我的 Windows Application
在同一个解决方案中,我用它来生成动态代码。
CompilerResult returns 这些错误:
The type or namespace name 'TestApp' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'User' could not be found (are you missing a using directive or an assembly reference?)
这是我的代码:
StringBuilder sbCode = new StringBuilder();
sbCode.Append(@"using System.Windows.Forms;");
sbCode.Append(@"using Nikola.BusinessIntelligence.Objects;");
sbCode.Append(@"using System.Collections.Generic;");
sbCode.Append(@"using System.Text;");
sbCode.Append(@"using Microsoft.CSharp;");
sbCode.Append(@"using TestApp.Data;"); // User class is in this Class Lib
sbCode.Append(" public class Test {");
sbCode.Append(tbCode.Text);
sbCode.Append("}");
var cp = new CompilerParameters()
{
GenerateInMemory = true,
GenerateExecutable = false,
ReferencedAssemblies =
{
"System.dll",
"System.Core.dll",
"System.Windows.dll",
"System.Windows.Forms.dll",
},
};
using (CSharpCodeProvider codeProvider = new CSharpCodeProvider())
{
CompilerResults res = codeProvider.CompileAssemblyFromSource(cp, sbCode.ToString());
var type = res.CompiledAssembly.GetType("Test");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}
这是我在 tbCode 文本框中编写的示例代码:
public User Execute()
{
User usr = new User();
return usr;
}
两个问题:
你忘了namespace
:
sbCode.Append(" namespace SomeNameSpace{public class Test {");
sbCode.Append(tbCode.Text);
sbCode.Append("}}");
您正在尝试的代码中缺少 =
:
User usr = new User();
关于编译器错误,您必须添加缺少的程序集。尝试像这样添加当前程序集使用的所有内容:
var options = new CompilerParameters();
// add all loaded assemblies
options.ReferencedAssemblies.AddRange(
AppDomain.CurrentDomain.GetAssemblies().Where(item => !item.IsDynamic).Select(item => item.Location).ToArray());
options.GenerateExecutable = false;
options.GenerateInMemory = true;
// compile like this
var result = provider.CompileAssemblyFromSource(options, source);
if (result.Errors.HasErrors)
{
// deal with errors
}
显然,如果您在代码中键入 using something;
,则必须在 CompilerParameters
中使用的引用程序集列表中添加 something
相关的引用程序集:
var cp = new CompilerParameters()
{
GenerateInMemory = true,
GenerateExecutable = false,
ReferencedAssemblies =
{
"System.dll",
"System.Core.dll",
"System.Windows.dll",
"System.Windows.Forms.dll",
// I assume the following name of the assembly
// however you should update it to the relevant name if needed
"TestApp.Data.dll"
},
};
我想从 Codedom 创建的函数中 return 自定义 class(例如 User
)。我的 User
class 在另一个 class 库中,与我的 Windows Application
在同一个解决方案中,我用它来生成动态代码。
CompilerResult returns 这些错误:
The type or namespace name 'TestApp' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'User' could not be found (are you missing a using directive or an assembly reference?)
这是我的代码:
StringBuilder sbCode = new StringBuilder();
sbCode.Append(@"using System.Windows.Forms;");
sbCode.Append(@"using Nikola.BusinessIntelligence.Objects;");
sbCode.Append(@"using System.Collections.Generic;");
sbCode.Append(@"using System.Text;");
sbCode.Append(@"using Microsoft.CSharp;");
sbCode.Append(@"using TestApp.Data;"); // User class is in this Class Lib
sbCode.Append(" public class Test {");
sbCode.Append(tbCode.Text);
sbCode.Append("}");
var cp = new CompilerParameters()
{
GenerateInMemory = true,
GenerateExecutable = false,
ReferencedAssemblies =
{
"System.dll",
"System.Core.dll",
"System.Windows.dll",
"System.Windows.Forms.dll",
},
};
using (CSharpCodeProvider codeProvider = new CSharpCodeProvider())
{
CompilerResults res = codeProvider.CompileAssemblyFromSource(cp, sbCode.ToString());
var type = res.CompiledAssembly.GetType("Test");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}
这是我在 tbCode 文本框中编写的示例代码:
public User Execute()
{
User usr = new User();
return usr;
}
两个问题:
你忘了
namespace
:sbCode.Append(" namespace SomeNameSpace{public class Test {"); sbCode.Append(tbCode.Text); sbCode.Append("}}");
您正在尝试的代码中缺少
=
:User usr = new User();
关于编译器错误,您必须添加缺少的程序集。尝试像这样添加当前程序集使用的所有内容:
var options = new CompilerParameters();
// add all loaded assemblies
options.ReferencedAssemblies.AddRange(
AppDomain.CurrentDomain.GetAssemblies().Where(item => !item.IsDynamic).Select(item => item.Location).ToArray());
options.GenerateExecutable = false;
options.GenerateInMemory = true;
// compile like this
var result = provider.CompileAssemblyFromSource(options, source);
if (result.Errors.HasErrors)
{
// deal with errors
}
显然,如果您在代码中键入 using something;
,则必须在 CompilerParameters
中使用的引用程序集列表中添加 something
相关的引用程序集:
var cp = new CompilerParameters()
{
GenerateInMemory = true,
GenerateExecutable = false,
ReferencedAssemblies =
{
"System.dll",
"System.Core.dll",
"System.Windows.dll",
"System.Windows.Forms.dll",
// I assume the following name of the assembly
// however you should update it to the relevant name if needed
"TestApp.Data.dll"
},
};