C# FieldBuilder-您如何设置默认值?
我使用TypeBuilder在运行时创建类型,但似乎不知道如何设置字段的默认值 例如,假设我想在运行时使用TypeBuilder创建以下布局,如何将默认值“m_number”(设置为64) 下面是我用来创建属性的代码。。。如何设置字段的值为“defaultValue”C# FieldBuilder-您如何设置默认值?,c#,dynamic,default-value,typebuilder,C#,Dynamic,Default Value,Typebuilder,我使用TypeBuilder在运行时创建类型,但似乎不知道如何设置字段的默认值 例如,假设我想在运行时使用TypeBuilder创建以下布局,如何将默认值“m_number”(设置为64) 下面是我用来创建属性的代码。。。如何设置字段的值为“defaultValue” void AddProperty(string name, Type type, object defaultValue) { // Add a private field of type
void AddProperty(string name, Type type, object defaultValue)
{
// Add a private field of type
FieldBuilder fieldBuilder = m_typeBuilder.DefineField("m_" + name.ToLower(), type, FieldAttributes.Private);
// Define a property that gets and sets the private field. The last argument of DefineProperty is null, because the
// property has no parameters. (If you don't specify null, you must specify an array of Type objects. For a parameterless property,
// use the built-in array with no elements: Type.EmptyTypes)
PropertyBuilder propertyBuilder = m_typeBuilder.DefineProperty(name, PropertyAttributes.HasDefault, type, null);
// The property "set" and property "get" methods require a special set of attributes.
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
// Define the "get" accessor method. The method returns the value and has no arguments. (Note that null could be
// used instead of Types.EmptyTypes)
MethodBuilder getAccessorMethodBuilder = m_typeBuilder.DefineMethod("get_" + name, getSetAttr, type, Type.EmptyTypes);
// For an instance property, argument zero is the instance. Load the instance, then load the private
//field and return, leaving the field value on the stack.
ILGenerator numberGetIL = getAccessorMethodBuilder.GetILGenerator();
numberGetIL.Emit(OpCodes.Ldarg_0);
numberGetIL.Emit(OpCodes.Ldfld, fieldBuilder);
numberGetIL.Emit(OpCodes.Ret);
// Define the "set" accessor method for Number, which has no return type and takes one argument of type T.
MethodBuilder setAccessorMethodBuilder = m_typeBuilder.DefineMethod("set_" + name, getSetAttr, null, new Type[] { type });
// Load the instance and then the argument, then store the argument in the 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 the "get" and "set" accessor methods to the PropertyBuilder. The property is now complete.
propertyBuilder.SetGetMethod(getAccessorMethodBuilder);
propertyBuilder.SetSetMethod(setAccessorMethodBuilder);
}
当有疑问时,以IL模式询问Roslyn:-) 默认字段在对象的构造函数中设置:
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at 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
请注意,如果有多个构造函数,则链接到同一类的其他构造函数的构造函数似乎不会设置该值,而不链接到同一类的其他构造函数的构造函数则会设置该值。请参阅扩展示例:
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at 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