如何使用反射在C#中获取一个方法的所有属性和属性数据

3
最终目标是将一个方法中的属性“原封不动”地复制到生成类中的另一个方法中。
public class MyOriginalClass
{
    [Attribute1]
    [Attribute2("value of attribute 2")]
    void MyMethod(){}
}

public class MyGeneratedClass
{
    [Attribute1]
    [Attribute2("value of attribute 2")]
    void MyGeneratedMethod(){}
}

我可以使用MethodInfo.GetCustomAttributes()列出方法的属性,但这不会给我属性参数;而我需要生成相应的属性以在生成的类上使用。

请注意,我不知道属性的类型(无法强制转换Attribute)。

我正在使用CodeDom生成代码。

2个回答

4

MethodInfo.GetCustomAttributesData()方法包含所需信息:

// method is the MethodInfo reference
// member is CodeMemberMethod (CodeDom) used to generate the output method; 
foreach (CustomAttributeData attributeData in method.GetCustomAttributesData())
{
    var arguments = new List<CodeAttributeArgument>();
    foreach (var argument in attributeData.ConstructorArguments)
    {
        arguments.Add(new CodeAttributeArgument(new CodeSnippetExpression(argument.ToString())));
    }

    if (attributeData.NamedArguments != null)
        foreach (var argument in attributeData.NamedArguments)
        {
            arguments.Add(new CodeAttributeArgument(new CodeSnippetExpression(argument.ToString())));
        }

    member.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(attributeData.AttributeType), arguments.ToArray()));
}

那段代码能够区分上述例子中的情况吗? - John Saunders
是的,这就是为什么有两个for循环,一个用于构造函数参数,另一个用于命名参数。我测试了这两种情况,并成功地复制了注释。 - nbilal

1
我不认为这是可能的。GetCustomAttributes返回一个对象数组,其中每个对象都是自定义属性的实例。无法知道使用哪个构造函数创建了该实例,因此无法知道如何创建用于该构造函数的代码(这就是属性语法的含义)。
例如,你可能有:
[Attribute2("value of attribute 2")]
void MyMethod(){}

"

Attribute2" 可以定义为:

"
public class Attribute2 : Attribute {
    public Attribute2(string value) { }
    public Attribute2() {}
    public string Value{get;set;}
}

无法知道它是由谁生成的

[Attribute2("value of attribute 2")]

或通过。
[Attribute2(Value="value of attribute 2")]

1
实际上有一种方法...请看下面我的答案。 - nbilal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接