反射发出:如何转换属性实例CustomAttributeBuilder或一个CustomAttributeData [英] Reflection Emit: how to Convert Attribute instance to CustomAttributeBuilder or CustomAttributeData

查看:587
本文介绍了反射发出:如何转换属性实例CustomAttributeBuilder或一个CustomAttributeData的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我提出,建立在此基础上实现的接口接口的代理类生成器类

I made a generator class that build a proxy class based on interface which implement the interface.

请参阅我的文章上的构建基于接口的代理类没有实现它

我熟悉 CustomAttributeData.GetCustomAttributes(目标的MemberInfo),我用它当我读到该接口的成员,并成功将它们导入到代理服务器。

I'm familiar with CustomAttributeData.GetCustomAttributes(MemberInfo target), I used it when I read the Interface's members and succeed to import them to the proxy.

我要注入的更多属性生成的类在运行时。
我所要求的属性的情况下将其注入到代理服务器

I want to inject additional attributes to generated class in run-time. I'm asking for attributes instances to inject them into the proxy.

例如:

一个开发者可以通过这个作为一个值:新ObsoleteAttribute(演示,真),(它有一个空的构造,但性能只读),我想将其转换为:

A developer can pass this as a value: new ObsoleteAttribute("Demo", true), (it has an empty constructor, but properties are read only), and I want to convert it to:

return new CustomAttributeBuilder(
               attribute.GetType().GetConstructor(Type[] {typeof (string), typeof (bool)}),
               new object[] {"Demo", true},
               new FieldInfo[0], 
               new object[0]);



记住,我不知道是什么给出。

Remember, I can't tell what is given.

推荐答案

这是不是一个通用的解决方案,但如果你愿意勉强你们那些参数构造函数和读/写属性和字段支持的属性将工作

This is not a general solution, but will work if you are willing to constrain the attributes you support to those with parameterless constructors and Read/Write Properties and Fields

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());
}

要做到一个通用的解决方案,您可以使用表达式。这是比较复杂的,但允许的语法如下:

To do a general solution, you could use expressions. That is more complicated, but would allow syntax like:

BuildCustomAttribute(() => new ObsoleteAttribute("Demo", true));



解析表达式提取的构造信息和参数将是复杂的部分,但它可以是。完成

Parsing the expression to extract the constructor info and the parameters would be the complex part, but it can be done.

CustomAttributeBuilder BuildCustomAttribute(Expression<Action> exp)
{
    //extract ConstructorInfo from exp
    //extract ParameterValues from exp
    //extract Attribute Type from exp

    return new CustomAttributeBuilder(ConstructorInfo, ParameterValues);
}

这篇关于反射发出:如何转换属性实例CustomAttributeBuilder或一个CustomAttributeData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆