使用Roslyn生成readonly record struct时遇CS0106错误求助
解决Roslyn生成readonly record struct的CS0106错误
你的问题出在readonly修饰符的语法构造方式不对——在Roslyn中,readonly是record struct的特定关键字,不能通过普通的AddModifiers方法添加,需要使用RecordDeclaration专门的WithReadOnlyKeyword方法来设置。另外还要确保编译时指定支持该特性的C#版本(至少C# 9.0)。
修正后的代码
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; var tree = SyntaxFactory.CompilationUnit() .AddMembers( SyntaxFactory.RecordDeclaration( SyntaxFactory.Token(SyntaxKind.RecordKeyword), SyntaxFactory.Identifier("A")) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .WithClassOrStructKeyword(SyntaxFactory.Token(SyntaxKind.StructKeyword)) .WithReadOnlyKeyword(SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)) // 改用专门方法设置readonly .WithParameterList(SyntaxFactory.ParameterList())) .NormalizeWhitespace(); Console.WriteLine(tree.ToFullString()); var refApis = AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.IsDynamic) .Select(a => MetadataReference.CreateFromFile(a.Location)); // 指定支持readonly record struct的C#版本 var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithLanguageVersion(LanguageVersion.CSharp9); var compilation = CSharpCompilation.Create("something", new SyntaxTree[] { tree.SyntaxTree }, refApis, options); var diag = compilation.GetDiagnostics().Where(e => e.Severity == DiagnosticSeverity.Error).ToList(); foreach (var d in diag) { Console.WriteLine(d); } Console.ReadLine();
关键修改点
- 移除
AddModifiers中的readonly令牌,改用WithReadOnlyKeyword方法设置该关键字——这是Roslyn针对record struct语法设计的专属API,符合C#语法规则中readonly修饰record struct的逻辑。 - 在编译选项中添加
.WithLanguageVersion(LanguageVersion.CSharp9),确保编译时启用支持readonly record struct的语言特性。
运行修正后的代码,生成的语法树会正确输出public readonly record struct A();,且不会再触发CS0106错误。
内容的提问来源于stack exchange,提问作者ASi
相关产品推荐
相关产品推荐

