有没有什么方法可以准确确定在声明属性时使用了哪个构造函数,以及传入的值?例如,如果一个方法标记为Obsolete("message")
(而不是Obsolete("message", true)
),我可以检索单个参数构造函数吗?获取属性构造函数声明为
我问的原因是我正在做代码生成,我想复制在我生成的类上给定的方法或类上声明的属性。 GetCustomAttributes()
只显示为我提供的属性及其值的类型,但除非我错过了某些信息不足以重复该属性实际声明的方式。
有没有什么方法可以准确确定在声明属性时使用了哪个构造函数,以及传入的值?例如,如果一个方法标记为Obsolete("message")
(而不是Obsolete("message", true)
),我可以检索单个参数构造函数吗?获取属性构造函数声明为
我问的原因是我正在做代码生成,我想复制在我生成的类上给定的方法或类上声明的属性。 GetCustomAttributes()
只显示为我提供的属性及其值的类型,但除非我错过了某些信息不足以重复该属性实际声明的方式。
您是否尝试过使用CustomAttributeData.GetCustomAttributes
方法来获取属性构造函数的详细信息。我试图用一个属性装饰类和它的作品如预期,这应该是相同的属性装饰方法等等
一个完整的例子:
[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);
}
}
而且,我不是绝对的把握这个,但我相信安全属性是特殊的,所以可能不可能发现确切的构造函数。然而,我似乎无法回想起我从哪里得到这个想法,所以不要认为这是理所当然的。
要确定使用哪个构造函数,您需要查看IL代码。
如果我没有记错的话,你会发现声明为构造函数方法调用的自定义属性。解决ConstructorInfo
会给你它的参数。
哇!你有我在CustomAttributeData.GetCustomAttributes。神奇,详细,非常详尽的答案,非常感谢。至于获取属性构造函数的值,可以从CustomAttributeData.ConstructorArguments中获得。 – 2011-04-03 02:33:36