2015-11-30 6 views
1

Я пытаюсь Acces свойство класса мой метод MethodBuilder в настоящее время определен в Это мой текущий код:.MethodBuilder ILGenerator получить класс недвижимости

Type[] types = { typeof(HttpListenerContext) }; 
TypeBuilder tb = GetTypeBuilder(type.Name); 
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); 
MethodBuilder mB = tb.DefineMethod("Init", MethodAttributes.Public | MethodAttributes.Virtual, null, types); 
ILGenerator il = mB.GetILGenerator(); 

il.Emit(OpCodes.Ldstr, typeof(Page).GetProperty("_POST").GetValue(??)); 
il.Emit(OpCodes.Call, typeof(DataSet).GetMethod("SetData")); 
il.Emit(OpCodes.Ret); 

tb.DefineMethodOverride(mB, typeof(Page).GetMethod("Init")); 

try 
{ 
    Type tc = tb.CreateType(); 
    Page test = (Page)Activator.CreateInstance(tc); 
    test.Init(); 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e.Message); 
} 

Это классно, что я пытаюсь получить имущество от:

public class Page 
{ 
    public Dictionary<string, string> _POST { get; set; } 
    public Dictionary<string, string> _GET { get; set; } 
    public Head Headers { get; set; } 
    public string ContentType { get; set; } 
    public int StatusCode = 200; 

    public virtual void Init(HttpListenerContext ctx = null) { } 

    public virtual void Load() { } 

    public virtual string Send() { return ""; } 
    public virtual string Send(string response) { return ""; } 
} 

в настоящее время TypeBuilder имеет страницу как родитель, как я могу получить нестатическое значение, установленное в моем классе TypeBuilder? Как я могу получить мой метод для Console.WriteLine значение _POST?

private TypeBuilder GetTypeBuilder(string name) 
{ 
    string typeSignature = name; 
    AssemblyName aN = new AssemblyName(typeSignature); 
    AssemblyBuilder aB = AppDomain.CurrentDomain.DefineDynamicAssembly(aN, AssemblyBuilderAccess.Run); 
    ModuleBuilder mB = aB.DefineDynamicModule("MainModule"); 
    TypeBuilder tB = mB.DefineType(typeSignature + "h", 
    TypeAttributes.Public | 
    TypeAttributes.Class | 
    TypeAttributes.AutoClass | 
    TypeAttributes.AnsiClass | 
    TypeAttributes.BeforeFieldInit | 
    TypeAttributes.AutoLayout, 
    typeof(Page)); 

    return tB; 
} 


    ILGenerator il = mB.GetILGenerator(); 

    il.Emit(OpCodes.Ldarg_0); 
    il.Emit(OpCodes.Ldstr, typeof(Page).GetProperty("ContentType").GetGetMethod()); 
    il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); 
    il.Emit(OpCodes.Ret); 

    tb.DefineMethodOverride(mB, typeof(Page).GetMethod("Init")); 

Я устанавливаю значение ContentType, прежде чем получаю его с помощью моей функции.

+1

Самый простой способ решить этот тип проблем - написать код, который вы пытаетесь сгенерировать в C#, а затем ildasm it. –

+0

@zespri Итак, я должен написать короткую строку, например 'Console.WriteLine (this._POST);' и затем ildasm? –

+0

Ну, да, просто не забудьте положить его в метод/класс, который вы пытаетесь создать. Но см. Ответ Luaan ниже для возможного готового решения. –

ответ

1

Кажется, вы создаете метод экземпляра для типа, который наследуется от Page. Если это так, то это код, который вы хотите:

il.Emit(OpCodes.Ldarg_0); // Load the this reference 
il.Emit(OpCodes.Call, typeof(Page).GetProperty("_POST").GetGetMethod()); 

Кроме того, обратите внимание, что DataSet не имеет SetData метод - если это метод расширения, вам нужно использовать реальный тип, где он определен, а не DataSet.

+0

Выполняя эти строки: 'il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Call, typeof (Page) .GetProperty ("_ POST"). GetGetMethod()); 'Я получаю ошибку Jit-компилятор обнаружил внутреннее ограничение. Чем это вызвано? –

+0

@StijnBernards в вашем вопросе вы пытаетесь 'ldstr'' Словарь'. Это явно не сработает. Это ваша проблема? –

+0

Я думаю, что не так, как сейчас, я вызываю функцию get переменной _POST и возвращаю ошибку, я добавил функцию typebuilder, возможно, я испортил расширение класса? –