Roslyn:ISymbol.GetAttributes 返回继承的属性

xtm*_*tmq 5 roslyn roslyn-code-analysis

Roslyn 具有ISymbol与各种有用方法的接口。我试图通过 获取所有类属性ISymbol.GetAttributes。这是文档链接:

https://learn.microsoft.com/de-de/dotnet/api/microsoft.codeanalysis.isymbol.getattributes?view=roslyn-dotnet

正如我们所看到的,没有指示该方法是否返回继承的属性(来自基类的属性)。这是第一个问题。第二个问题 - 为什么文档中没有提及这一点?

Aid*_*api 4

我不知道为什么文档中没有提及它,并且认为应该在那里提及。

由于我面临同样的问题,我测试了它,它不会返回继承的属性。您可以使用这些扩展方法来获取所有属性,包括继承的属性:

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;
}
Run Code Online (Sandbox Code Playgroud)