简体   繁体   中英

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

I'm using Reflection.Emit to define a dynamic type. The class inherits from a generic base class. In C# this would all look like this:

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:

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. It's obviously possible to generate code to do this since the C# code works just fine. 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? That is, I would expect you to be using typeof(DataReaderMapper<ISomeInterface>) , not typeof(DataReaderMapper<T>) , based on your C# example.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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