用Reflection.Emit创建一个带有属性的接口

本文关键字:一个 属性 接口 Emit Reflection 创建 | 更新日期: 2023-09-27 18:15:43

我需要生成一个接口。生成(发射)虚拟属性是一个问题。似乎它们不是生成的。

我知道我做错了什么:

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

我做错了什么?

用Reflection.Emit创建一个带有属性的接口

属性没有正确定义。为了使GetProperty工作,属性必须至少有一个公共getter或setter。现在,它甚至没有一个getter或setter,因此它们永远不能是公共的。

所以,你必须创建一个公共的get-method和/或公共的set-method(使用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);
}