Get Attribute Constructor As It was Declared
Is there any way to determine exactly which constructor was used when an attribute was declared and the values that were passed in? For instance if a method is marked with Obsolete("message")
(as opposed to Obsolete("message", true)
) can I retrieve that single parameter constructor?
The reason I ask is that I am doing code generation and I want to duplicate the attributes that were declared on a given method or class on my generated class. GetCustomAttributes()
only appears to provide me the type of the attribute and its values, but unless I'm missing something that's not enough information to duplicate the way the attribute was a开发者_Go百科ctually declared.
Have you tried to use CustomAttributeData.GetCustomAttributes
method to obtain detailed information for the attribute constructor. I tried with an attribute decorating a class and it works as expected, it should be the same for attributes decorating methods, etc.
A complete example:
[Obsolete("Fubar!", false)]
class Foo { }
[Obsolete("Fubar!")]
class Bar { }
static void Main(string[] args)
{
// Prints: ObsoleteAttribute(String message, Boolean error)
PrintAttributeCtorInfo(typeof(Foo));
// Prints: ObsoleteAttribute(String message)
PrintAttributeCtorInfo(typeof(Bar));
}
private static void PrintAttributeCtorInfo(Type type)
{
foreach (var item in CustomAttributeData.GetCustomAttributes(type))
{
var parameters = item.Constructor.GetParameters();
string paramsList = String.Join(
", ",
parameters.Select(pi => pi.ParameterType.Name + " " + pi.Name));
Console.WriteLine(
"{0}({1})",
item.Constructor.DeclaringType.Name,
paramsList);
}
}
Also, I'm not absolutely sure about this, but I believe that security attributes are kind of special so it may be impossible to discover the exact constructor used. However, I can't seem to recall from where I got this idea, so don't take it as granted.
To determine which of the contructors that was used you'll need to have a look at the IL-code.
If I remember correctly you'll find custom attributes declared as a call to a constructor method. Resolving the ConstructorInfo
gives you its parameters.
精彩评论