如何在c#中生成一个新类型

本文关键字:一个 新类型 类型 | 更新日期: 2023-09-27 17:54:25

我真的想在运行时生成一个新的类型。本质上,我想创建的类型看起来像这样:

public class MySpecial123
{
    public Func<int, DateTime, int> salesVectorCalc; // field
    public int CallSalesVectorCalculation(int i, DateTime d)
    (
        return salesVectorCalc(i, d);
    )
}

一些类型将根据用户/数据库输入而变化,所以我不能真正完成它,然后在运行时创建类型。还有更复杂的,但我想让我的问题简单,所以我只问最基本的问题。我将需要做更多的生成,就像你在这里看到的。

我想使用Reflection.Emit会很酷,但后来我意识到在内存中生成代码和编译可能更容易。有人知道哪个更好吗?我真的很想看一个例子,如何做到这两个

如何在c#中生成一个新类型

当你说"在运行时生成类型"时,听起来好像你在要求动态类型

在c# 4.0中,只需使用动态关键字即可完成。

然而,你也描述了类似于代码生成的东西——如果这是你所追求的,为什么不使用像T4模板这样的东西在"预编译"阶段生成你的类型?

很容易将代码生成为字符串,然后将其动态编译为内存中的程序集。然后,您可以调用方法并通过以下方式访问字段:

  • 使用反射
  • 使用动态关键字
  • 转换到接口/基类(如果你的新类继承自一个)
代码:

public static Assembly Compile(string source)
{
    var codeProvider = new CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.0" } });
    var compilerParameters = new CompilerParameters();
    compilerParameters.ReferencedAssemblies.Add("System.dll");
    compilerParameters.ReferencedAssemblies.Add("System.Core.dll");
    compilerParameters.ReferencedAssemblies.Add("System.Xml.dll");
    compilerParameters.ReferencedAssemblies.Add("System.Xml.Linq.dll");
    compilerParameters.CompilerOptions = "/t:library";
    compilerParameters.GenerateInMemory = true;
    var result = codeProvider.CompileAssemblyFromSource(compilerParameters, source);
    if (result.Errors.Count > 0)
    {
        foreach (CompilerError error in result.Errors)
        {
            Debug.WriteLine("ERROR Line {0:000}: {1}", error.Line, error.ErrorText);
        }
        return null;
    }
    else
    {
        return result.CompiledAssembly;
    }
}