使用PropertyBuilder和SetConstant设置属性的默认值

时间:2012-08-16 15:54:34

标签: c# .net reflection properties reflection.emit

我有一段相当简单的代码

var propertyBuilder =
    typeBuilder.DefineProperty(upperName, PropertyAttributes.None, propertyType, new[] { propertyType });
propertyBuilder.SetConstant(Convert.ChangeType(propertyInfo.Default, propertyType));

之后,当我调用CreateType()方法并创建类的实例时,我试图检查属性的值,并指定默认值,但我看不到任何更改。

在创建类的实例后,我无法使用SetValue方法,因为所有构造的类型都存储在元数据字典中,可以在代码中的不同位置使用。

为什么SetConstant方法不起作用的任何建议?

1 个答案:

答案 0 :(得分:2)

SetConstant()没有按照您的想法行事。它设置了与属性关联的“默认值”,但该值实际上并未在任何地方使用(尽管您可以使用GetConstantValue()检索它。)

要从属性的getter实际返回一些常量值,您需要创建getter方法并设置其IL以返回值。但由于您无法在程序集本身中存储任意类型,因此通常很难做到这一点。例如,如果属性为int,则它将如下所示:

var getMethodBuilder = typeBuilder.DefineMethod(
    "get_" + upperName, MethodAttributes.Public, typeof(int), Type.EmptyTypes);

var il = getMethodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldc_I4, defaultValue);
il.Emit(OpCodes.Ret);

var propertyBuilder = typeBuilder.DefineProperty(
    upperName, PropertyAttributes.None, typeof(int), Type.EmptyTypes);
propertyBuilder.SetGetMethod(getMethodBuilder);

ldc.i4是一个IL指令,用于将常量整数加载到IL堆栈。对于其他类型,您需要不同的说明。