c# - FieldBuilder - Ho do you set the default value? -
i'm using typebuilder create types @ runtime, can't seem figure out how set default value of field.
for example, wanted create following layout @ runtime, using typebuilder, how set default value of 'm_number' (to 64)?
public class dynamictype1 { private int m_number = 64; public int number { { return m_number; } set { m_number = value; } } }
here code use create property, ... how set field have value of 'defaultvalue'
void addproperty(string name, type type, object defaultvalue) { // add private field of type fieldbuilder fieldbuilder = m_typebuilder.definefield("m_" + name.tolower(), type, fieldattributes.private); // define property gets , sets private field. last argument of defineproperty null, because // property has no parameters. (if don't specify null, must specify array of type objects. parameterless property, // use built-in array no elements: type.emptytypes) propertybuilder propertybuilder = m_typebuilder.defineproperty(name, propertyattributes.hasdefault, type, null); // property "set" , property "get" methods require special set of attributes. methodattributes getsetattr = methodattributes.public | methodattributes.specialname | methodattributes.hidebysig; // define "get" accessor method. method returns value , has no arguments. (note null // used instead of types.emptytypes) methodbuilder getaccessormethodbuilder = m_typebuilder.definemethod("get_" + name, getsetattr, type, type.emptytypes); // instance property, argument 0 instance. load instance, load private //field , return, leaving field value on stack. ilgenerator numbergetil = getaccessormethodbuilder.getilgenerator(); numbergetil.emit(opcodes.ldarg_0); numbergetil.emit(opcodes.ldfld, fieldbuilder); numbergetil.emit(opcodes.ret); // define "set" accessor method number, has no return type , takes 1 argument of type t. methodbuilder setaccessormethodbuilder = m_typebuilder.definemethod("set_" + name, getsetattr, null, new type[] { type }); // load instance , argument, store argument in field. ilgenerator numbersetil = setaccessormethodbuilder.getilgenerator(); numbersetil.emit(opcodes.ldarg_0); numbersetil.emit(opcodes.ldarg_1); numbersetil.emit(opcodes.stfld, fieldbuilder); numbersetil.emit(opcodes.ret); // last, map "get" , "set" accessor methods propertybuilder. property complete. propertybuilder.setgetmethod(getaccessormethodbuilder); propertybuilder.setsetmethod(setaccessormethodbuilder); }
when in doubt, ask roslyn, in il mode :-) http://goo.gl/nebcep
the default field set in constructor(s) of object:
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // method begins @ rva 0x2061 // code size 15 (0xf) .maxstack 8 il_0000: ldarg.0 il_0001: ldc.i4.s 64 il_0003: stfld int32 dynamictype1::m_number
note if there multiple constructors, seems constructors chain other constructors of same class don't set value, while constructors don't chain other constructor of same class set. see expanded example: http://goo.gl/8y90ku
Comments
Post a Comment