Roslyn分析器中如何判断类是否标记为partial?
Roslyn判断类是否标记为partial的实现方案
INamedTypeSymbol没有提供类似IMethodSymbol.PartialImplementationPart的直接属性来判断类是否为分部类,你可以通过检查类符号关联的语法节点修饰符实现该需求,具体实现逻辑如下:
实现步骤
- 首先获取目标类对应的
INamedTypeSymbol实例 - 遍历实例的
DeclaringSyntaxReferences属性,该属性会返回当前类所有分部定义的语法节点引用(非分部类只会返回1个引用,分部类无论写了几个分部,都会返回对应数量的引用) - 将每个语法节点转换为对应的声明类型(类对应
ClassDeclarationSyntax,结构体对应StructDeclarationSyntax,记录对应RecordDeclarationSyntax),检查其Modifiers集合中是否存在partial关键字
代码示例
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; // 扩展方法:判断类型是否为分部类 public static bool IsPartialType(this INamedTypeSymbol typeSymbol) { foreach (var syntaxReference in typeSymbol.DeclaringSyntaxReferences) { var syntaxNode = syntaxReference.GetSyntax(); // 处理partial class if (syntaxNode is ClassDeclarationSyntax classDecl) { if (classDecl.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))) return true; } // 如需支持partial struct 放开下方注释 // if (syntaxNode is StructDeclarationSyntax structDecl) // { // if (structDecl.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))) // return true; // } // 如需支持partial record 放开下方注释 // if (syntaxNode is RecordDeclarationSyntax recordDecl) // { // if (recordDecl.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))) // return true; // } } return false; }
注意事项
- 不要仅通过
DeclaringSyntaxReferences.Count > 1判断是否为分部类:如果用户仅写了一个带partial修饰的类定义,还没有其他分部实现时,该集合长度为1,但此时已经允许你生成分部类的第二部分。 - 你可以根据你的Source Generator支持的目标类型,裁剪对应类型的判断逻辑,降低性能开销。
内容的提问来源于stack exchange,提问作者maxc137
相关产品推荐
相关产品推荐

