有沒有什麼方法可以準確確定在聲明屬性時使用了哪個構造函數,以及傳入的值?例如,如果一個方法標記爲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