1

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# コードは問題なく動作するため、これを行うコードを生成することは明らかに可能です。Reflection.Emit で実際にサポートされていないコンパイラが実行できることがおそらくあると思いますが、これがそのようなケースではないことを願っています。

このインスタンスの基本クラスのフィールドにアクセスする方法を知っている人はいますか?

助けてくれてありがとう

4

1 に答える 1

1

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.

于 2012-12-07T20:56:05.697 に答える