C#:为什么我看不到我的类(动态创建)属性

时间:2017-12-30 07:43:42

标签: c# class dynamic builder

我将创建一个类构建器类。它工作正常,我的课程是根据我需要的数据创建的。但我看不到添加到课程中的属性。

这是我的班级建设者类:

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

3 个答案:

答案 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%的代码将会消失,你开始使用的问题将会消失。