我将创建一个类构建器类。它工作正常,我的课程是根据我需要的数据创建的。但我看不到添加到课程中的属性。
这是我的班级建设者类:
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace aitClassBuilder
{
public interface IclassBuilder
{
float Read(Int32 first, Int32 second);
string Write();
}
public class ClassBuilder : IclassBuilder
{
AssemblyName asemblyName;
public ClassBuilder(string ClassName, string ClassId)
{
this.asemblyName = new AssemblyName(ClassName);
}
public object CreateObject()
{
TypeBuilder DynamicClass = this.CreateClass();
this.CreateConstructor(DynamicClass);
CreateProperty(DynamicClass, "ColumnId", Type.GetType("System.Int32"));
CreateProperty(DynamicClass, "ColumnName", Type.GetType("System.String"));
Type type = DynamicClass.CreateType();
return Activator.CreateInstance(type);
}
private TypeBuilder CreateClass()
{
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(this.asemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType(this.asemblyName.FullName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null);
return typeBuilder;
}
private void CreateConstructor(TypeBuilder typeBuilder)
{
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
}
private void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
{
FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIl = getPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);
MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType });
ILGenerator setIl = setPropMthdBldr.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
public float Read(Int32 first, Int32 second)
{
return first + second;
}
public string Write()
{
string result = "";
return result;
}
}
}
我从这个类中使用:
aitClassBuilder.ClassBuilder myCls =
new ClassBuilder("Sys_Columns", "1003");
object myTbl = myCls.CreateObject();
MessageBox.Show(myTbl.ColumnID);
在此代码的末尾,当我想要访问我的类的ColumnID属性时,发生了一个错误。但是当我将类添加到监视窗口时,我可以看到属性已添加到我的类中。我不知道为什么? 你能帮帮我吗?
错误详情是: 错误CS1061'object'不包含'ColumnID'的定义,也没有扩展方法'ColumnID'接受类型'object'的第一个参数(你是否缺少using指令或汇编引用?)FormSample E:\ New Hafiz \ aitClassBuilder \ FormSample \ Form1.cs 29 Active
答案 0 :(得分:2)
由于错误消息表明object
类型没有名为ColumnID
的属性。由于您无法将对象强制转换为实际类型,因此您必须在此处使用dynamic关键字。所以你的代码将是:
dynamic myTbl = myCls.CreateObject();
MessageBox.Show(myTbl.ColumnID);
请注意,您不会使用此方法对属性类型进行任何编译时检查。
答案 1 :(得分:0)
您必须将对象转换为(Sys_Columns)。
Sys_Columns myTbl = (Sys_Columns)myCls.CreateObject();
答案 2 :(得分:0)
那里发生了什么?
0_o。
为什么要动态生成一个全新的课程而不是创建另一个Dictionary<string, object>
?如果您更喜欢坚持使用强类型(我假设您这样做,否则为什么需要C#?),可能会声明扩展方法TResult TryGetValue<TResult>(this Dictionary<string, object> @this, string key)
。
因此,你出现的95%的代码将会消失,你开始使用的问题将会消失。