使用Roslyn API生成代码遇CS7069错误:找不到CancellationToken类型
解决Roslyn编译时CS7069: 找不到CancellationToken在System.Runtime中的定义问题
这个错误的核心原因是你对.NET Core/.NET 5+的程序集引用模型理解有误——你手动添加的System.Runtime.dll其实是一个facade(占位)程序集,它并不包含CancellationToken的实际类型定义,真正的实现存在于.NET共享框架的运行时组件中。直接从磁盘路径引用这类占位dll,Roslyn自然找不到类型。
下面是几种可行的解决方案:
1. 直接从类型获取正确的程序集引用
不要手动查找磁盘上的dll,而是通过typeof()直接获取包含目标类型的程序集,这样能确保引用到真正包含类型定义的组件:
// 获取CancellationToken所在的正确程序集 Compilation = Compilation.AddReferences(MetadataReference.CreateFromAssembly(typeof(CancellationToken).Assembly)); // 添加基础类型所在的程序集(比如object) Compilation = Compilation.AddReferences(MetadataReference.CreateFromAssembly(typeof(object).Assembly));
这种方式绕开了手动找dll的麻烦,让CLR自动定位到正确的程序集。
2. 确保编译选项与目标框架匹配
检查你的CSharpCompilation对象是否设置了正确的目标框架版本,这会影响Roslyn查找程序集的逻辑:
var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithTargetFramework(TargetFrameworkMoniker.Parse(".NET6.0")); // 根据你的实际框架版本调整 // 初始化编译时传入这个选项 var compilation = CSharpCompilation.Create("MyAssembly", syntaxTrees: new[] { yourSyntaxTree }, options: compilationOptions);
3. 使用Workspace自动管理框架引用
如果你的场景允许,使用Roslyn的AdhocWorkspace来创建项目和编译,它会自动处理目标框架的引用依赖,无需手动添加:
var workspace = new AdhocWorkspace(); var projectId = ProjectId.CreateNewId(); var projectInfo = ProjectInfo.Create( projectId, VersionStamp.Default, "MyGeneratedProject", "MyGeneratedAssembly", LanguageNames.CSharp, compilationOptions: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithTargetFramework(TargetFrameworkMoniker.Parse(".NET6.0"))); var project = workspace.AddProject(projectInfo); // 添加你的生成代码语法树到项目 project = project.AddDocument("MyGeneratedClass.cs", yourSyntaxTree).Project; // 获取自动处理了引用的编译对象 var compilation = await project.GetCompilationAsync();
补充说明
在.NET Core/.NET 5+中,框架程序集不再像.NET Framework那样是独立的磁盘dll,而是以共享框架的形式存在。你之前找到的System.Runtime.dll只是一个用于编译时的facade,它的作用是引导编译器找到共享框架中的实际实现,所以单独引用它毫无意义。通过类型直接获取程序集,或者让Workspace自动管理引用,才是正确的姿势。
内容的提问来源于stack exchange,提问作者Puchacz
相关产品推荐
相关产品推荐

