简体   繁体   English

Reflection.Emit访问动态构造的类的基类中的字段

[英]Reflection.Emit accessing a field in the base class of a dynamically constructed class

I'm using Reflection.Emit to define a dynamic type. 我正在使用Reflection.Emit定义动态类型。 The class inherits from a generic base class. 该类继承自通用基类。 In C# this would all look like this: 在C#中,它们看起来都像这样:

public abstract class DataReaderMapper<T>
{
  protected readonly IDataReader reader_;

  protected DataReaderMapper(IDataReader reader) {
    reader_ = reader;
  }
}

public class SomeDataReaderMapper: DataReaderMapper<ISomeInterface> {
  public string SomeProperty {
    get { return reader_.GetString(0); }
  }
}

The Reflection.Emit part: Reflection.Emit部分:

Type MakeDynamicType() {
    TypeBuilder builder = module_.DefineType(
      GetDynamicTypeName(),
      TypeAttributes.Public |
        TypeAttributes.Class |
        TypeAttributes.AutoClass |
        TypeAttributes.AutoLayout,
      typeof (DataReaderMapper<T>),
      new Type[] {type_t_});

    ConstructorBuilder constructor =
      type.DefineConstructor(MethodAttributes.Public |
         MethodAttributes.HideBySig |
         MethodAttributes.SpecialName |
         MethodAttributes.RTSpecialName,
        CallingConventions.Standard, new Type[] {typeof (IDataReader)});

     ConstructorInfo data_reader_mapper_ctor = typeof (DataReaderMapper<T>)
       .GetConstructor(new Type[] {typeof (IDataReader)});
     ILGenerator il = constructor.GetILGenerator();
     il.Emit(OpCodes.Ldarg_0);
     il.Emit(OpCodes.Ldarg_1);
     il.Emit(OpCodes.Call, data_reader_mapper_ctor);

     il.Emit(OpCodes.Ret);

     PropertyBuilder property_builder = builder
       .DefineProperty(property.Name, PropertyAttributes.HasDefault,
         property.PropertyType, null);

     MethodBuilder get_method = builder.DefineMethod("get_" + property.Name,
       MethodAttributes.Public |
         MethodAttributes.SpecialName |
         MethodAttributes.HideBySig);

     ILGenerator il = get_method.GetILGenerator();
     il.Emit(OpCodes.Ldarg_0);

     // *********************
     //  How can I access the reader_ field of the base class.
     // *********************

     property_builder.SetGetMethod(get_method);
}

The problem is I'm trying to generate SomeDerivedDataMapper dynamically using Reflection.Emit, but I do not know how to access the protected field of the base class. 问题是我正在尝试使用Reflection.Emit动态生成SomeDerivedDataMapper,但是我不知道如何访问基类的受保护字段。 It's obviously possible to generate code to do this since the C# code works just fine. 显然有可能生成代码来执行此操作,因为C#代码可以正常工作。 I suppose there are probably things that compilers can do that aren't actually supported by Reflection.Emit but I'm hoping this isn't one of those cases. 我想反射器实际上可能不支持编译器可以做的事情,但是我希望这不是这些情况之一。

Does anybody have any idea how to access the fields in the base class in this instance? 有谁知道在这种情况下如何访问基类中的字段?

Thanks for any help 谢谢你的帮助

Your code has lots of other problems, too, but how is the identifier T bound in your MakeDynamicType method? 您的代码也有很多其他问题,但是如何在MakeDynamicType方法中绑定标识符T That is, I would expect you to be using typeof(DataReaderMapper<ISomeInterface>) , not typeof(DataReaderMapper<T>) , based on your C# example. 也就是说,根据您的C#示例,我希望您使用typeof(DataReaderMapper<ISomeInterface>) ,而不是typeof(DataReaderMapper<T>)

In any case, you should be able to do something like: 无论如何,您应该可以执行以下操作:

var fld = typeof(DataReaderMapper<ISomeInterface>)
    .GetField("reader_", BindingFlags.NonPublic | BindingFlags.Instance);

to get the field, and then use il.Emit(OpCodes.Ldfld, fld) to get the field from the instance. 获取该字段,然后使用il.Emit(OpCodes.Ldfld, fld)从实例获取该字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM