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

C# 如何在C中使用反射获取方法的所有属性和属性数据#,c#,reflection,C#,Reflection,最终目标是将属性“按原样”从一个方法复制到生成类中的另一个方法 public class MyOriginalClass { [Attribute1] [Attribute2("value of attribute 2")] void MyMethod(){} } public class MyGeneratedClass { [Attribute1] [Attribute2("value of attribute 2")] void MyGen

最终目标是将属性“按原样”从一个方法复制到生成类中的另一个方法

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

public class MyGeneratedClass
{
    [Attribute1]
    [Attribute2("value of attribute 2")]
    void MyGeneratedMethod(){}
}
我可以使用
MethodInfo.GetCustomAttributes()
列出方法的属性,但是,这并没有给我属性参数;我需要在生成的类上生成相应的属性

注意,我不知道属性的类型(不能强制转换属性)


我正在使用CodeDom生成代码。

我不知道如何才能做到这一点。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")]
或者


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()));
}
//方法是MethodInfo引用
//成员是用于生成输出方法的CodeMemberMethod(CodeDom);
foreach(方法.GetCustomAttributesData()中的CustomAttributeData attributeData)
{
var参数=新列表();
foreach(attributeData.ConstructorArguments中的变量参数)
{
Add(新的CodeAttributeArgument(新的CodeSnippetExpression(argument.ToString())));
}
if(attributeData.NamedArguments!=null)
foreach(attributeData.NamedArguments中的var参数)
{
Add(新的CodeAttributeArgument(新的CodeSnippetExpression(argument.ToString())));
}
Add(新的CodeAttributeDeclaration(新的CodeTypeReference(attributeData.AttributeType),arguments.ToArray());
}

实际上有一种方法。。请看下面我的答案。这段代码能区分上面示例中的情况吗?是的,这就是为什么有两个for循环,一个用于构造函数参数,一个用于命名参数。我对这两种情况都进行了测试,并正确复制了注释。
// 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()));
}