2

I am trying to create new object for given type and load it to the field, but it throws an

InvalidProgramException.

Doing same using locals works. Maybe doing something wrong with fields? This does not work:

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

But this works:

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

So what is the difference and why first not working? Thanks.

René Vogt
  • 43,056
  • 14
  • 77
  • 99
Druid
  • 23
  • 2

1 Answers1

1

Non-static fields need an object reference.

A better way to generate IL is to use expression trees.

Also, you can answer all such questions yourself by writing the equivalent code in C# and decompiling the compiler output.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Thanks for reply. I investigated the generated IL, and one question also, so it means that I can't create object and put it in the created non-static field using this kind of approach? – Druid Mar 24 '16 at 18:47
  • 1
    Of course, but you need to store it in to field of a particular object. Not sure I understand your question... Does it make sense to you to store into a non-static field without providing an object that field lives in?! – usr Mar 24 '16 at 18:54
  • Well, I am trying to create data proxy generator, so for given type which implements some interface, I am trying to create something like wrapper class, so using appropriate getters. But the issue is becoming then the class types not the same in interface and in input object type. I mean in object property is type of "A" in interface it is type of "B". So that is why trying to create appropriate type of object and set nested fields. – Druid Mar 24 '16 at 19:07
  • Not sure I understand the issue. Do you understand that an object reference is required to set an instance field? In that IL you have not provided an object reference. – usr Mar 24 '16 at 19:13
  • I understanding it. So my question is how can I do that? See, I have this kind of types: ClassA-> A1 Prop1; C1 Prop2 and ClassB->B1 Prop1, C1Prop2. I have an object of class A, and want to using Emit create wrapper object to work with object as type of ClassB. For Prop2 it is working,I am calling GetGetMethods from ClassA, but for Prop1 it is not working beacuse the Geters have different types.So question is, how can I do that? – Druid Mar 24 '16 at 19:15
  • 1
    I don't fully understand the scenario. But that's also not the question asked. Ask a new one. This one is done: You now know what the problem is. Make an attempt to provide an object reference. I have not seen any such attempt so I can't help you point out mistakes. – usr Mar 24 '16 at 19:56