Reflection Emit:如何将Attribute实例转换为CustomAttributeBuilder或CustomAttributeData
我创建了一个生成器类,它基于实现接口的接口构建代理类。
请参阅我在基于接口构建代理类的post而不实现它 。
我熟悉CustomAttributeData.GetCustomAttributes(MemberInfo target)
,当我读取Interface的成员并成功将它们导入代理时,我使用它。
我想在运行时向生成的类注入其他属性。 我要求将属性实例注入代理中。
例如:
开发人员可以将其作为值传递: new ObsoleteAttribute("Demo", true)
,(它有一个空构造函数,但属性是只读的),我想将其转换为:
return new CustomAttributeBuilder( attribute.GetType().GetConstructor(Type[] {typeof (string), typeof (bool)}), new object[] {"Demo", true}, new FieldInfo[0], new object[0]);
记住,我不知道给出了什么。
这不是一般解决方案,但如果您愿意将支持的属性约束到具有无参数构造函数和读/写属性和字段的属性,则可以使用它。
CustomAttributeBuilder BuildCustomAttribute(System.Attribute attribute) { Type type = attribute.GetType(); var constructor = type.GetConstructor(Type.EmptyTypes); var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); var propertyValues = from p in properties select p.GetValue(attribute, null); var fieldValues = from f in fields select f.GetValue(attribute); return new CustomAttributeBuilder(constructor, Type.EmptyTypes, properties, propertyValues.ToArray(), fields, fieldValues.ToArray()); }
要做一般解决方案,您可以使用表达式。 这更复杂,但允许语法如下:
BuildCustomAttribute(() => new ObsoleteAttribute("Demo", true));
解析表达式以提取构造函数信息和参数将是复杂的部分,但它可以完成。
CustomAttributeBuilder BuildCustomAttribute(Expression exp) { //extract ConstructorInfo from exp //extract ParameterValues from exp //extract Attribute Type from exp return new CustomAttributeBuilder(ConstructorInfo, ParameterValues); }
谢谢乔,
由于您的输入,我确实在Attribute Builder中找到了Expression
解决方案。
我现在愿意更努力地让其他开发人员更容易使用我的代理 。
我希望它可以更容易,如果我有属性实例,为什么我不能按原样使用它并应用属性?
如果你有一个没有Expression
的解决方案,我很乐意听到它。
这是基于Attribute Builder的 Expression
的解决方案:
private CustomAttributeBuilder GetCustumeAttributeBuilder(Expression> attributeExpression) { ConstructorInfo constructor = null; List
如果我正确理解了这个问题,那么应该为生成的类型添加自定义属性
public class CustomAttribute: System.Attribute { public CustomAttribute() { } } TypeBuilder typeBuilder = module.DefineType(...)
….
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder( typeof(CustomAttribute).GetConstructor(Type.EmptyTypes), Type.EmptyTypes, new FieldInfo[0], new object[0]));