当前位置: 首页 > 编程语言 > C#

ReflectionEmit:如何将属性实例转换为CustomAttributeBuilder或CustomAttributeData分享

时间:2023-04-10 13:51:53 C#

ReflectionEmit:如何将属性实例转换为CustomAttributeBuilder或CustomAttributeData我创建了一个构建器类,它基于实现接口的接口构建代理类。请参阅我关于在不实现接口的情况下基于接口构建代理类的帖子。我熟悉CustomAttributeData.GetCustomAttributes(MemberInfotarget),我在读取接口成员并将它们成功导入代理时使用它。我想在运行时向生成的类注入额外的属性。我需要将属性实例注入代理。例如:开发人员可以将其作为值传递:newObsoleteAttribute("Demo",true),(它有一个空的构造函数,但该属性是只读的),我想将其转换为:returnnewCustomAttributeBuilder(attribute.GetType().GetConstructor(Type[]{typeof(string),typeof(bool)}),newobject[]{"Demo",true},newFieldInfo[0],newobject[0]);记住,我不知道给出的是什么。这不是通用解决方案,但如果您愿意将支持的属性限制为具有无参数构造函数的属性以及读/写属性和字段,则可以使用它。CustomAttributeBuilderBuildCustomAttribute(System.Attributeattribute){Typetype=attribute.GetType();varconstructor=type.GetConstructor(Type.EmptyTypes);varproperties=type.GetProperties(BindingFlags.Public|BindingFlags.Instance);varfields=type.GetFields(BindingFlags.Public|BindingFlags.Instance);varpropertyValues=frompinpropertiesselectp.GetValue(attribute,null);varfieldValues=fromfinfieldsselectf.GetValue(attribute);返回新的CustomAttributeBuilder(构造函数,Type.EmptyTypes,属性,propertyValues.ToArray(),字段,fieldValues.ToArray());对于通用解决方案,您可以使用表达式。这更复杂,但允许这样的语法:BuildCustomAttribute(()=>newObsoleteAttribute("Demo",true));解析表达式以提取构造函数信息和参数将是复杂的部分,但可以完成。CustomAttributeBuilderBuildCustomAttribute(Expressionexp){//从exp中提取ConstructorInfo//从exp中提取ParameterValues//从exp中提取属性类型returnnewCustomAttributeBuilder(ConstructorInfo,ParameterValues);谢谢Joe,感谢您的输入,我确实在AttributeBuilder中找到了表达式解决方案。我现在愿意更加努力地工作,让我的代理更容易被其他开发人员使用。我希望它可以更容易,如果我有属性实例,为什么我不能按原样使用它并应用属性?如果您有没有Expression的解决方案,我很想听听。这是基于属性生成器的表达式的解决方案:privateCustomAttributeBuilderGetCustumeAttributeBuilder(ExpressionattributeExpression){列表构造函数Args=newList();列出namedProperties=newList();列表propertyValues=newList();列出namedFields=newList();列表字段值=newList();开关(attributeExpression.Body.NodeType){caseExpressionType.New:constructor=GetConstructor((NewExpression)attributeExpression.Body,constructorArgs);休息;caseExpressionType.MemberInit:MemberInitExpressioninitExpression=(MemberInitExpression)attributeExpression.Body;构造函数=GetConstructor(initExpression.NewExpression,constructorArgs);IEnumerablebindings=frombininitExpression.Bindingswhereb.BindingType==MemberBindingType.AssignmentselectbasMemberAssignment;foreach(绑定中的MemberAssignment赋值){LambdaExpressionlambda=Expression.Lambda(assignment.Expression);对象ct值=lambda.Compile().DynamicInvoke();switch(assignment.Member.MemberType){caseMemberTypes.Field:namedFields.Add((FieldInfo)assignment.Member);fieldValues.Add(值);休息;caseMemberTypes.Property:namedProperties.Add((PropertyInfo)assignment.Member);propertyValues.Add(值);休息;}}休息;默认值:抛出新的ArgumentException("UnSupportedExpression","attributeExpression");}returnnewCustomAttributeBuilder(构造函数,constructorArgs.ToArray(),namedProperties.ToArray(),propertyValues.ToArray(),namedFields.ToArray(),fieldValues.ToArray());}privateConstructorInfoGetConstructor(NewExpressionexpression,ListconstructorArgs){foreach(Expressionarginexpression.Arguments){LambdaExpressionlambda=Expression.Lambda(arg);对象值=lambda.Compile().DynamicInvoke();constructorArgs.Add(值);}返回表达式。构造函数;如果我正确理解了这个问题,它应该将自定义属性添加到生成的类型publicclassCustomAttribute:System.Attribute{publicCustomAttribute(){}}TypeBuildertypeBuilder=module.DefineType(...)….以上就是C#学习教程:ReflectionEmit:HowtoconvertanAttributeinstancetoCustomAttributeBuilderorCustomAttributeData分享的所有内容,如果对大家有用,还需要详细了解C#学习教程,希望大家多多支持更多关注—typeBuilder.SetCustomAttribute(newCustomAttributeBuilder(typeof(CustomAttribute).GetConstructor(Type.EmptyTypes),Type.EmptyTypes,newFieldInfo[0],newobject[0]));本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: