Sie können eine nützliche Erweiterung Methode definieren ...
Type type = typeof(ProjectController);
var attributes = type.GetCustomAttributes<CustomDescriptionAttribute>(true);
Hier ist die Extension-Methode:
/// <summary>Searches and returns attributes. The inheritance chain is not used to find the attributes.</summary>
/// <typeparam name="T">The type of attribute to search for.</typeparam>
/// <param name="type">The type which is searched for the attributes.</param>
/// <returns>Returns all attributes.</returns>
public static T[] GetCustomAttributes<T>(this Type type) where T : Attribute
{
return GetCustomAttributes(type, typeof(T), false).Select(arg => (T)arg).ToArray();
}
/// <summary>Searches and returns attributes.</summary>
/// <typeparam name="T">The type of attribute to search for.</typeparam>
/// <param name="type">The type which is searched for the attributes.</param>
/// <param name="inherit">Specifies whether to search this member's inheritance chain to find the attributes. Interfaces will be searched, too.</param>
/// <returns>Returns all attributes.</returns>
public static T[] GetCustomAttributes<T>(this Type type, bool inherit) where T : Attribute
{
return GetCustomAttributes(type, typeof(T), inherit).Select(arg => (T)arg).ToArray();
}
/// <summary>Private helper for searching attributes.</summary>
/// <param name="type">The type which is searched for the attribute.</param>
/// <param name="attributeType">The type of attribute to search for.</param>
/// <param name="inherit">Specifies whether to search this member's inheritance chain to find the attribute. Interfaces will be searched, too.</param>
/// <returns>An array that contains all the custom attributes, or an array with zero elements if no attributes are defined.</returns>
private static object[] GetCustomAttributes(Type type, Type attributeType, bool inherit)
{
if(!inherit)
{
return type.GetCustomAttributes(attributeType, false);
}
var attributeCollection = new Collection<object>();
var baseType = type;
do
{
baseType.GetCustomAttributes(attributeType, true).Apply(attributeCollection.Add);
baseType = baseType.BaseType;
}
while(baseType != null);
foreach(var interfaceType in type.GetInterfaces())
{
GetCustomAttributes(interfaceType, attributeType, true).Apply(attributeCollection.Add);
}
var attributeArray = new object[attributeCollection.Count];
attributeCollection.CopyTo(attributeArray, 0);
return attributeArray;
}
/// <summary>Applies a function to every element of the list.</summary>
private static void Apply<T>(this IEnumerable<T> enumerable, Action<T> function)
{
foreach(var item in enumerable)
{
function.Invoke(item);
}
}
Update:
Hier ist eine kürzere Version, wie in einem Kommentar von Simond vorgeschlagen:
private static IEnumerable<T> GetCustomAttributesIncludingBaseInterfaces<T>(this Type type)
{
var attributeType = typeof(T);
return type.GetCustomAttributes(attributeType, true).
Union(type.GetInterfaces().
SelectMany(interfaceType => interfaceType.GetCustomAttributes(attributeType, true))).
Distinct().Cast<T>();
}
Sind Sie sich sicher? Die Methode MemberInfo.GetCustomAttributes benötigt ein Argument, das angibt, ob der Vererbungsbaum durchsucht werden soll. –
Hmm. Mir ist gerade aufgefallen, dass es bei der Frage darum geht, Attribute von einer Schnittstelle zu übernehmen, nicht von einer Basisklasse. –
Gibt es einen Grund, Attribute auf Schnittstellen zu setzen? –