2016-03-24 18 views
2

ich für gegebene Art neues Objekt zu erzeugen versuchen und es auf das Feld zu laden, aber es wirft einC# Dynamisches Assembly erstellen Können nicht neues Objekt und laden Feld

InvalidProgramException.

Das gleiche mit Einheimischen funktioniert. Vielleicht etwas falsch machen mit Feldern? Dies funktioniert nicht:

MethodAttributes getSetAttr = MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; 
FieldBuilder propNameBldr = typeBuilder.DefineField("_" + PropName, PropType, FieldAttributes.Private); 
propNamePropBldr = typeBuilder.DefineProperty(PropName, PropertyAttributes.HasDefault, PropType, null); 
propNameGetPropMthdBldr = typeBuilder.DefineMethod("get_" + PropName, getSetAttr, PropType, Type.EmptyTypes); 
ConstructorInfo baseCtor = basePropType.GetConstructor(new Type[] { }); 

ILGenerator propNameGetIL = propNameGetPropMthdBldr.GetILGenerator(); 

propNameGetIL.Emit(OpCodes.Newobj, baseCtor); 
propNameGetIL.Emit(OpCodes.Stfld, PropNameBldr); 

propNameGetIL.Emit(OpCodes.Ldfld, PropNameBldr); 
propNameGetIL.Emit(OpCodes.Ret); 
propNamePropBldr.SetGetMethod(propNameGetPropMthdBldr); 

Aber das funktioniert:

MethodAttributes getSetAttr = MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; 
FieldBuilder propNameBldr = typeBuilder.DefineField("_" + PropName, PropType, FieldAttributes.Private); 
propNamePropBldr = typeBuilder.DefineProperty(PropName, PropertyAttributes.HasDefault, PropType, null); 
propNameGetPropMthdBldr = typeBuilder.DefineMethod("get_" + PropName, getSetAttr, PropType, Type.EmptyTypes); 
ConstructorInfo baseCtor = basePropType.GetConstructor(new Type[] { }); 

ILGenerator propNameGetIL = propNameGetPropMthdBldr.GetILGenerator(); 
LocalBuilder lc = propNameGetIL.DeclareLocal(PropType); 
propNameGetIL.Emit(OpCodes.Newobj, baseCtor); 
propNameGetIL.Emit(OpCodes.Stloc, PropNameBldr); 

propNameGetIL.Emit(OpCodes.Ldloc, PropNameBldr); 
propNameGetIL.Emit(OpCodes.Ret); 
propNamePropBldr.SetGetMethod(propNameGetPropMthdBldr); 

Also, was ist der Unterschied und warum zuerst nicht? Vielen Dank.

Antwort

1

Nicht statische Felder benötigen eine Objektreferenz.

Eine bessere Möglichkeit zum Generieren von IL ist die Verwendung von Ausdrucksbäumen.

Sie können alle diese Fragen auch selbst beantworten, indem Sie den entsprechenden Code in C# schreiben und die Compilerausgabe dekompilieren.

+0

Danke für die Antwort. Ich untersuchte die generierte IL und auch eine Frage. Es bedeutet also, dass ich mit dieser Art von Ansatz kein Objekt erstellen und es in das erzeugte nicht-statische Feld einfügen kann. – Druid

+1

Natürlich, aber Sie müssen es im Feld eines bestimmten Objekts speichern. Nicht sicher, dass ich deine Frage verstehe ... Macht es Sinn, in ein nicht-statisches Feld zu speichern, ohne ein Objekt zu liefern, in dem das Feld lebt ?! – usr

+0

Nun, ich versuche, Daten-Proxy-Generator zu erstellen, also für gegebene Art, die eine Schnittstelle implementiert, ich versuche, etwas wie Wrapper-Klasse zu erstellen, so dass entsprechende Getter verwenden. Aber das Problem wird dann die Klassenarten nicht in der Schnittstelle und im Eingabeobjekttyp gleich. Ich meine in Objekteigenschaft ist Typ von "A" in der Schnittstelle ist es Typ von "B". Deshalb versuchen Sie, einen geeigneten Objekttyp zu erstellen und verschachtelte Felder zu setzen. – Druid