Roslyn has ISymbol
interface with various useful methods. I'm trying to get all class attributes via ISymbol.GetAttributes
. This is a documentation link:
As we can see there is no indication if this method returns inherited attributes (attributes from base classes) or not. So this is the first questions. The second question - why there is no mentions about that in documentation?
I don't know why there's no mention of it in the documentation, and think it should be mentioned there.
Since I was facing the same issue, I tested it, and it will not return inherited attributes. You can use these extension methods to get all attributes including the inherited ones:
public static IEnumerable<AttributeData> GetAttributesWithInherited(this INamedTypeSymbol typeSymbol) {
foreach (var attribute in typeSymbol.GetAttributes()) {
yield return attribute;
}
var baseType = typeSymbol.BaseType;
while (baseType != null) {
foreach (var attribute in baseType.GetAttributes()) {
if (IsInherited(attribute)) {
yield return attribute;
}
}
baseType = baseType.BaseType;
}
}
private static bool IsInherited(this AttributeData attribute) {
if (attribute.AttributeClass == null) {
return false;
}
foreach (var attributeAttribute in attribute.AttributeClass.GetAttributes()) {
var @class = attributeAttribute.AttributeClass;
if (@class != null && @class.Name == nameof(AttributeUsageAttribute) &&
@class.ContainingNamespace?.Name == "System") {
foreach (var kvp in attributeAttribute.NamedArguments) {
if (kvp.Key == nameof(AttributeUsageAttribute.Inherited)) {
return (bool) kvp.Value.Value!;
}
}
// Default value of Inherited is true
return true;
}
}
// An attribute without an `AttributeUsage` attribute will also default to being inherited.
return true;
}