2012-12-07 71 views
1

我正在使用Reflection.Emit來定義動態類型。該類從 繼承了一個通用基類。在C#這都會是這樣的:Reflection.Emit訪問動態構造類的基類中的字段

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

問題是我想產生SomeDerivedDataMapper動態使用 Reflection.Emit的,但我不知道如何訪問基類的保護字段 。顯然可以生成代碼,因爲C#代碼工作得很好。我想有可能編譯器可以做的事情, 實際上並不支持Reflection.Emit,但我希望這不是這些情況下的一個 。

有沒有人有任何想法如何訪問這個實例中的基類 中的字段?

感謝所有幫助

+2

你的問題是什麼,顯示一些代碼? – leppie

+2

如果您可以使用'Reflection.Emit'發佈您的嘗試,可能會有所幫助。 – McGarnagle

回答

1

你的代碼有很多其他的問題,太多,但如何標識TMakeDynamicType法約束?也就是說,我希望你使用typeof(DataReaderMapper<ISomeInterface>),而不是typeof(DataReaderMapper<T>),基於你的C#示例。

在任何情況下,你應該能夠做這樣的事情:

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

獲取字段,然後用il.Emit(OpCodes.Ldfld, fld)從實例獲得現場。

+0

MakeDynamicType是DataReaderMapper內部類的一個功能 nohros