3

我正在开发一个文档生成器。MSDN 文档显示了在应用时传递给 Attributes 的参数。比如[ComVisibleAttribute(true)]。我将如何通过反射、pdb 文件或其他方式获取这些参数值和/或在我的 c# 代码中调用的构造函数?

澄清>如果有人记录了一个具有如下属性的方法:

/// <summary> foo does bar </summary>
[SomeCustomAttribute("a supplied value")]
void Foo() {
  DoBar();
}

我希望能够在我的文档中显示该方法的签名,如下所示:

Signature:

[SomeCustomAttribute("a supplied value")]
void Foo();
4

2 回答 2

6

如果您有想要获取自定义属性和构造函数参数的成员,可以使用以下反射代码:

MemberInfo member;      // <-- Get a member

var customAttributes = member.GetCustomAttributesData();
foreach (var data in customAttributes)
{
    // The type of the attribute,
    // e.g. "SomeCustomAttribute"
    Console.WriteLine(data.AttributeType);

    foreach (var arg in data.ConstructorArguments)
    {
        // The type and value of the constructor arguments,
        // e.g. "System.String a supplied value"
        Console.WriteLine(arg.ArgumentType + " " + arg.Value);
    }
}

要获取成员,请从获取类型开始。有两种获取类型的方法。

  1. 如果您有实例obj,请调用Type type = obj.GetType();.
  2. 如果您有类型名称MyType,请执行Type type = typeof(MyType);

然后你可以找到,例如,一个特定的方法。查看反射文档以获取更多信息。

MemberInfo member = typeof(MyType).GetMethod("Foo");
于 2013-02-21T23:14:45.767 回答
3

对于ComVisibileAttribute,传递给构造函数的参数成为Value属性。

[ComVisibleAttribute(true)]
public class MyClass { ... }

...

Type classType = typeof(MyClass);
object[] attrs = classType.GetCustomAttributes(true);
foreach (object attr in attrs)
{
    ComVisibleAttribute comVisible = attr as ComVisibleAttribute;
    if (comVisible != null)
    {
        return comVisible.Value // returns true
    }
}

其他属性将遵循类似的设计模式。


编辑

我发现这篇关于Mono.Cecil的文章描述了如何做一些非常相似的事情。这看起来它应该做你需要的。

foreach (CustomAttribute eca in classType.CustomAttributes)
{
    Console.WriteLine("[{0}({1})]", eca, eca.ConstructorParameters.Join(", "));
}
于 2013-02-21T23:03:12.830 回答