我有一个类,它看起来像这样:

public class Field
{
    public string FieldName;
    public string FieldType;
}

和一个对象列表<字段>值:

{"EmployeeID","int"},
{"EmployeeName","String"},
{"Designation","String"}

我想创建一个类,看起来像这样:

Class DynamicClass
{
    int EmployeeID,
    String EmployeeName,
    String Designation
}

有什么办法可以做到吗?

我希望它在运行时生成。我不希望在文件系统中驻留一个物理CS文件。


当前回答

你可以使用system . runtime . remoting . agents . realproxy。它将允许您使用“正常”代码,而不是低级程序集类型的东西。

请参阅RealProxy对这个问题的回答,以获得一个好例子:

我如何拦截一个方法调用在c# ?

其他回答

你可以使用system . runtime . remoting . agents . realproxy。它将允许您使用“正常”代码,而不是低级程序集类型的东西。

请参阅RealProxy对这个问题的回答,以获得一个好例子:

我如何拦截一个方法调用在c# ?

您可以考虑使用动态模块和类来完成这项工作。唯一的缺点是它仍然加载在应用程序域中。但是。net 4.0支持可收集的动态程序集,因此你可以动态地重新创建类/类型。

我不知道这种动态类的预期用途,代码生成和运行时编译是可以完成的,但需要一些努力。 也许匿名类型会帮助你,比如:

var v = new { EmployeeID = 108, EmployeeName = "John Doe" };

您还可以使用DynamicExpressions动态地创建类。

因为'Dictionary'有紧凑的初始化器并处理键冲突,所以你会想这样做。

  var list = new Dictionary<string, string> {
    {
      "EmployeeID",
      "int"
    }, {
      "EmployeeName",
      "String"
    }, {
      "Birthday",
      "DateTime"
    }
  };

或者,您可能希望使用JSON转换器将序列化的字符串对象构造为可管理的对象。

然后使用System.Linq.Dynamic;

  IEnumerable<DynamicProperty> props = list.Select(property => new DynamicProperty(property.Key, Type.GetType(property.Value))).ToList();

  Type t = DynamicExpression.CreateClass(props);

剩下的就是使用System.Reflection。

  object obj = Activator.CreateInstance(t);
  t.GetProperty("EmployeeID").SetValue(obj, 34, null);
  t.GetProperty("EmployeeName").SetValue(obj, "Albert", null);
  t.GetProperty("Birthday").SetValue(obj, new DateTime(1976, 3, 14), null);
}  

这需要一些工作,但肯定不是不可能的。

我所做的是:

在字符串中创建c#源代码(不需要写入文件), 通过Microsoft.CSharp.CSharpCodeProvider (CompileAssemblyFromSource)运行它 查找生成的类型 并创建该类型的实例(Activator.CreateInstance)

这样您就可以处理已经知道的c#代码,而不必发出MSIL。

但是,如果你的类实现了一些接口(或从一些基类派生),这是最好的工作,否则调用代码(阅读:编译器)如何知道将在运行时生成的类?