[英]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.