簡體   English   中英

Reflection.Emit訪問動態構造的類的基類中的字段

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

我正在使用Reflection.Emit定義動態類型。 該類繼承自通用基類。 在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); }
  }
}

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);
}

問題是我正在嘗試使用Reflection.Emit動態生成SomeDerivedDataMapper,但是我不知道如何訪問基類的受保護字段。 顯然有可能生成代碼來執行此操作,因為C#代碼可以正常工作。 我想反射器實際上可能不支持編譯器可以做的事情,但是我希望這不是這些情況之一。

有誰知道在這種情況下如何訪問基類中的字段?

謝謝你的幫助

您的代碼也有很多其他問題,但是如何在MakeDynamicType方法中綁定標識符T 也就是說,根據您的C#示例,我希望您使用typeof(DataReaderMapper<ISomeInterface>) ,而不是typeof(DataReaderMapper<T>)

無論如何,您應該可以執行以下操作:

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

獲取該字段,然后使用il.Emit(OpCodes.Ldfld, fld)從實例獲取該字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM