使用Reflection.Emit创建一个包含属性的接口

时间:2015-10-01 13:00:08

标签: c# reflection.emit

我需要生成一个界面。 我生成(发出)虚拟属性的问题。它们似乎没有生成。

我发现我做错了什么:

private static TypeBuilder getTypeBuilder()
    {
        var typeSignature = "DynamicDigitalInput";
        var an = new AssemblyName(typeSignature);

        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicDomain");
        TypeBuilder tb = moduleBuilder.DefineType(typeSignature
                            , TypeAttributes.Public |
                            TypeAttributes.Interface |
                            TypeAttributes.Abstract |
                            TypeAttributes.AutoClass |
                            TypeAttributes.AnsiClass |
                            TypeAttributes.BeforeFieldInit |
                            TypeAttributes.AutoLayout
                            , null);

        return tb;
    }

    private static void createProperty(TypeBuilder tb, string propertyName, Type propertyType)
    {

        PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
    }

为了生成界面:

TypeBuilder tb = getTypeBuilder();
createProperty(tb, "p1", String.GetType());
createProperty(tb, "p2", Int32.GetType());

当我执行此操作时:

Type i = tb.CreateType();
System.Reflection.PropertyInfo p1 = type.GetProperty("p1");

p1null

我做错了什么?

1 个答案:

答案 0 :(得分:2)

未正确定义属性。为了使GetProperty起作用,该属性必须至少有一个公共getter或setter。现在,甚至没有一个吸气剂或二传手,所以他们永远不会公开。

因此,您必须创建一个公共get方法和/或一个公共set方法(使用MethodBuilder)。试试这个:

private static void createProperty(TypeBuilder tb, string propertyName, Type propertyType)
{
    PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
    MethodBuilder methodBuilder = tb.DefineMethod("get_" + propertyName, MethodAttributes.Virtual | MethodAttributes.Abstract | MethodAttributes.Public);
    propertyBuilder.SetGetMethod(methodBuilder);
}