使用 Roslyn 判断 class 是否为记录
Determine whether class is a record using Roslyn
我正在编写一个源代码生成器,需要知道我用 Microsoft.CodeAnalysis 添加功能的 class 是否是一条记录。
我可以通过切换到语法模型来做到这一点,就像这样:
public static bool IsRecord(this ITypeSymbol type)
{
if (type == null || type.TypeKind != TypeKind.Class)
return false;
bool isRecord = (type.DeclaringSyntaxReferences.Any(x => (x.SyntaxTree.GetRoot().FindNode(x.Span) is RecordDeclarationSyntax)));
return isRecord;
}
但是有什么方法可以用语义模型做到这一点吗?我可能遗漏了一些明显的东西,但我已经检查了在我看来是明显的地方,而且我还在 github 上进行了搜索。 Roslyn 中似乎有一个 internal IsRecord,但我找不到任何公开暴露的内容。如果我无法在语义模型中访问它,即使该类型来自从另一个程序集导入的代码,上述方法是否也能正常工作?
似乎没有任何官方 public 属性 IsRecord。因此,我们只能寻找记录包含的内容,例如隐式声明的 属性 名为“EqualityContract”:
type.GetMembers().Any(x => x.Kind == SymbolKind.Property && x.Name == "EqualityContract" && x.IsImplicitlyDeclared)
从 Roslyn API 的 3.9.0-2.final 版本开始(这对应于 Visual Studio 16.9 Preview 2),ITypeSymbol 现在有一个 IsRecord 属性 你可以用。
我正在编写一个源代码生成器,需要知道我用 Microsoft.CodeAnalysis 添加功能的 class 是否是一条记录。
我可以通过切换到语法模型来做到这一点,就像这样:
public static bool IsRecord(this ITypeSymbol type)
{
if (type == null || type.TypeKind != TypeKind.Class)
return false;
bool isRecord = (type.DeclaringSyntaxReferences.Any(x => (x.SyntaxTree.GetRoot().FindNode(x.Span) is RecordDeclarationSyntax)));
return isRecord;
}
但是有什么方法可以用语义模型做到这一点吗?我可能遗漏了一些明显的东西,但我已经检查了在我看来是明显的地方,而且我还在 github 上进行了搜索。 Roslyn 中似乎有一个 internal IsRecord,但我找不到任何公开暴露的内容。如果我无法在语义模型中访问它,即使该类型来自从另一个程序集导入的代码,上述方法是否也能正常工作?
似乎没有任何官方 public 属性 IsRecord。因此,我们只能寻找记录包含的内容,例如隐式声明的 属性 名为“EqualityContract”:
type.GetMembers().Any(x => x.Kind == SymbolKind.Property && x.Name == "EqualityContract" && x.IsImplicitlyDeclared)
从 Roslyn API 的 3.9.0-2.final 版本开始(这对应于 Visual Studio 16.9 Preview 2),ITypeSymbol 现在有一个 IsRecord 属性 你可以用。