Если вы хотите иметь возможность также получать пользовательские атрибуты, объявленные на интерфейсах, которые тип также реализует в дополнение к атрибутам в его цепочке наследования, вот способ linq-ish сделать это.
Сначала получите цепочку наследования:
// 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;
};
Эта функция похожа на ответ Джоша, но возвращает 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>