如何使用反射來確定在每個繼承級別應用了哪個屬性?如何關聯每個對象的屬性的.NET反射?
var AttributeArray = gUser.GetType().GetCustomAttributes(true);
如何使用反射來確定在每個繼承級別應用了哪個屬性?如何關聯每個對象的屬性的.NET反射?
var AttributeArray = gUser.GetType().GetCustomAttributes(true);
上繼承鏈每種類型呼叫GetCustomAttributes和通爲inherited
參數假。
Type t = gUser.GetType();
while (t != null && t != typeof(object)) {
var attributes = t.GetCustomAttributes(false);
// do something with this level of attributes
t = t.BaseType;
}
如果你希望能夠還得到該類型也實現除了那些在這裏繼承鏈的接口中聲明的自定義屬性是一個LINQ十歲上下的方式來做到這一點。
首先,得到繼承鏈:
// recursive lambda functions must initially be
// assigned null to allow recursive calls
Func<Type, IEnumerable<Type>> getInheritanceChain = null;
getInheritanceChain = t =>
{
IEnumerable<Type> ts = new [] { t, };
var bt = t.BaseType;
if (bt != null)
{
ts = ts.Concat(getInheritanceChain(bt));
}
return ts;
};
此功能類似於Josh的答案,但返回一個IEnumerable<Type>
,你可以用任何LINQ表達式中使用。
其次,將繼承鏈類型與由相關類型實現的接口類型連接起來。這給出了原始對象可以合法轉換爲的完整類型列表。
最後建立與類型爲關鍵和調用字典.GetCustomAttributes(false)
創建IEnumerable<Attribute>
類型的值:
Func<Type, IDictionary<Type, Attribute[]>> getCustomAttributesByType =
t => getInheritanceChain(t)
.Concat(t.GetInterfaces())
.ToDictionary(
x => x,
x => x.GetCustomAttributes(false)
.Cast<Attribute>()
.ToArray());
最終的結果是一個簡單的呼叫建立一個易於使用的字典。
IDictionary<Type, Attribute[]> lookup =
getCustomAttributesByType(gUser.GetType());
如果它針對System.String
運行字典包含以下值:
System.String
-> System.Reflection.DefaultMemberAttribute
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.SerializableAttribute
System.Object
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.Runtime.InteropServices.ClassInterfaceAttribute
-> System.SerializableAttribute
System.IComparable
-> System.Runtime.InteropServices.ComVisibleAttribute
System.ICloneable
-> System.Runtime.InteropServices.ComVisibleAttribute
System.IConvertible
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.CLSCompliantAttribute
System.IComparable<System.String>
System.Collections.Generic.IEnumerable<System.Char>
-> System.Runtime.CompilerServices.TypeDependencyAttribute
System.Collections.IEnumerable
-> System.Runtime.InteropServices.ComVisibleAttribute
-> System.Runtime.InteropServices.GuidAttribute
System.IEquatable<System.String>
+1了定神,我得知lamdas需要爲null,以遞歸。雖然我可以將屬性與對象關聯起來,但是我沒有能力知道我所處的繼承是什麼「級別」。假設我需要知道基礎屬性和第三個繼承者。好像我在這裏運氣不佳。 – LamonteCristo 2011-01-13 05:14:33