【发布时间】:2019-02-01 13:39:57
【问题描述】:
我正在编写一个 Roslyn 分析器来执行一些文档规则。规则规定,只有在程序集外可见的字段和类型才需要记录。这导致我发现一个字段或类型是否有效可见并且可以在声明程序集之外使用的问题。
鉴于此声明:
namespace TestApp {
internal class InternalClass {
public class InnerClass {
public int PublicFieldInInternal;
}
}
}
我想知道PublicFieldInInternal 在声明程序集之外是否可见。我使用下面的代码来确定可访问性:
private bool IsNonPrivateMemberDeclaration(SyntaxNodeAnalysisContext context, SyntaxNode node)
{
if (node is BaseFieldDeclarationSyntax fieldDeclaration)
{
var firstField = fieldDeclaration.Declaration.Variables.First();
var fieldAccessibility = context.SemanticModel.GetDeclaredSymbol(firstField).DeclaredAccessibility;
return ConstructVisibleFromOtherAssemblies(fieldAccessibility);
}
var accessibility = context.SemanticModel.GetDeclaredSymbol(node)?.DeclaredAccessibility;
if (accessibility != null)
{
return ConstructVisibleFromOtherAssemblies(accessibility.Value);
}
Debug.Assert(true, "This code should be unreachable as one of the two cases above will catch all calls");
return false;
}
private static bool ConstructVisibleFromOtherAssemblies(Accessibility accessibility) =>
accessibility == Accessibility.Public ||
accessibility == Accessibility.Protected ||
accessibility == Accessibility.ProtectedOrInternal;
但是,它没有考虑父类型的可访问性,因此PublicFieldInInternal 对应的符号的DeclaredAccessibility 属性返回Accessibility.Public。有没有办法直接查询语义模型以获得有效的可访问性,还是我需要递归查看包含类型?
【问题讨论】:
-
我很确定您必须递归查看包含类型。见
IsMemberAccessible。他们检查包含类型的IsNamedTypeAccessible。
标签: c# roslyn roslyn-code-analysis