在c#中动态创建一个类
本文关键字:一个 动态 创建 | 更新日期: 2023-09-27 18:18:19
我可以在运行时创建一个动态类,而事先不知道类的字段名吗?
例如,如果我让用户输入一个字符串列表,当他发送这个列表时,我创建一个类,用字段的名称作为字符串列表。
例如,如果我得到:
List<string> TempList = new List<string>() { "Name1", "Name2" };
我可以像这样在运行时创建一个类吗?
public class CustomClass(){
public string Name1;
public string Name2;
}
您可以在运行时使用反射创建类。如果你愿意,就释放吧。一种可能的方法是:
使用这个类来执行整个过程。用您希望属性使用的适当类型关闭类型T。在您的例子中,您将使用类型string。
class ClassFromList<T>
{
public object Instance { get; set; }
public ClassFromList(List<string> list)
{
var type = new DynamicClass().Builder;
list.ForEach(item => new DynamicProperty<T>(type, item));
Instance = Activator.CreateInstance(type.CreateType());
}
}
在上面提到的类中,这个类将为您提供TypeBuilder类型的属性,因此您可以在运行时创建一个类。
class DynamicClass
{
public TypeBuilder Builder { get; set; }
public DynamicClass()
{
var name = new AssemblyName("DynamicAssembly");
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
var module = assembly.DefineDynamicModule("DynamicModule");
Builder = module.DefineType("DynamicClass", TypeAttributes.Public);
}
}
而另一方面,下面的类将创建您希望您的类为您实现的属性。
class DynamicProperty<T>
{
public DynamicProperty(TypeBuilder builder, string name)
{
var field = builder.DefineField("_" + name, typeof(T), FieldAttributes.Private);
var property = builder.DefineProperty(name, PropertyAttributes.None, typeof(T), new Type[0]);
var getter = builder.DefineMethod("get_" + name, MethodAttributes.Public | MethodAttributes.SpecialName, typeof(T), new Type[0]);
var setter = builder.DefineMethod("set_" + name, MethodAttributes.Public | MethodAttributes.SpecialName, null, new Type[] { typeof(T) });
var getGenerator = getter.GetILGenerator();
var setGenerator = setter.GetILGenerator();
getGenerator.Emit(OpCodes.Ldarg_0);
getGenerator.Emit(OpCodes.Ldfld, field);
getGenerator.Emit(OpCodes.Ret);
setGenerator.Emit(OpCodes.Ldarg_0);
setGenerator.Emit(OpCodes.Ldarg_1);
setGenerator.Emit(OpCodes.Stfld, field);
setGenerator.Emit(OpCodes.Ret);
property.SetGetMethod(getter);
property.SetSetMethod(setter);
}
}
现在您只需要测试整个过程。下面的代码将创建3个名为"a","b","c"的字符串类型的属性,分别为它们添加值"value1","value2","value3",创建一个新类的实例,并显示所有的属性,它们的类型和值。
class Program
{
static void Main()
{
var list = new List<string>() { "a", "b", "c" };
var instance = new ClassFromList<string>(list).Instance;
instance.GetType().GetProperty("a").SetValue(instance, "value1", null);
instance.GetType().GetProperty("b").SetValue(instance, "value2", null);
instance.GetType().GetProperty("c").SetValue(instance, "value3", null);
instance.GetType()
.GetProperties()
.ToList()
.ForEach(x => Console.WriteLine(x.Name + " " + x.PropertyType + " " + x.GetValue(instance, null)));
Console.Read();
}
}
编辑:如果你确实需要在你的类字段,正如我刚刚注意到的,你应该使用DynamicField类,而不是DynamicProperty类,如下所示。但是请注意,对于对象之间的数据传输,属性比字段更可取。
class DynamicField<T>
{
public DynamicField(TypeBuilder builder, string name)
{
var field = builder.DefineField(name, typeof(T), FieldAttributes.Public);
}
}
您应该使用:
DynamicObject类
有一个如何使用它的链接:DynamicObject Class