关于c#:Reflection.Emit访问动态构造的类的基类中的字段

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

我正在使用Reflection.Emit定义动态类型。类继承自一个泛型基类。在C中,这一切看起来都是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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); }
  }
}

反射.发射部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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);
}

问题是我正在尝试使用反射。发射,但我不知道如何访问基类。显然可以生成代码来执行此操作,因为C代码工作得很好。我想可能有编译器可以做到的事情实际上反射不支持。发射,但我希望这不是一个在这些情况下。

有人知道如何访问中的基类中的字段吗?这个例子?

谢谢你的帮助


您的代码也有许多其他问题,但是在您的MakeDynamicType方法中,标识符T是如何绑定的?也就是说,根据您的C示例,我希望您使用的是typeof(DataReaderMapper),而不是typeof(DataReaderMapper)

在任何情况下,您都应该能够执行以下操作:

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

获取字段,然后使用il.Emit(OpCodes.Ldfld, fld)从实例中获取字段。