Roslyn编译为何仅含元数据引用或项目引用?及项目文档异常咨询
问题1:为何Roslyn编译仅包含元数据引用(Metadata References)或项目引用(Project References),而非同时包含两者?
这其实是Roslyn为了避免编译冲突、保证依赖一致性特意做的设计,咱们拆解下两种引用的本质就懂了:
- 项目引用:指向同一解决方案内的其他项目,Roslyn会实时追踪该项目的编译状态,直接用它的最新编译成果(而非已编译好的dll),还会自动梳理该项目的整个依赖链。
- 元数据引用:指向已经编译完成的.dll/.exe文件,相当于直接复用现成的程序集元数据。
如果允许同时存在同一目标的两种引用,就会出现致命歧义——比如你既引用了项目A,又引用了A上周编译的old.dll,Roslyn根本不知道该用哪个版本的代码/元数据。而且项目引用本身就会把依赖项目的最终输出作为元数据引入当前项目,再手动加元数据引用完全是重复操作,还容易引发版本不一致的问题。所以Roslyn的设计逻辑就是二选一,确保编译依赖的唯一性和正确性。
问题2:处理Roslyn中多出的生成文档
你碰到的多出来的文档,大概率是自动生成的代码文件(比如.Designer.cs、T4模板输出文件,或是其他工具生成的代码),这类文件默认会被Roslyn纳入Documents集合。要是想过滤掉它们,有两种简单的方式:
方式1:用Roslyn内置的扩展方法判断
先确保引用了Microsoft.CodeAnalysis命名空间,然后直接筛选非生成文档:
using Microsoft.CodeAnalysis; // 筛选出所有非自动生成的文档 var validDocuments = project.Documents.Where(doc => !doc.IsGeneratedDocument());
方式2:手动根据文件特征筛选
如果内置方法不够贴合你的场景,也可以根据文件路径的标识来判断(比如常见的生成文件命名规则):
var validDocuments = project.Documents.Where(doc => { var filePath = doc.FilePath; // 根据你的生成文件特征调整判断逻辑 return !filePath.Contains(".Designer.") && !filePath.EndsWith(".Generated.cs"); });
要是你只是在代码分析阶段需要忽略这些文件,直接筛选文档集合就足够了;如果想从项目层面排除生成文件,建议修改项目的MSBuild配置,而非通过Roslyn手动移除(毕竟生成文件是工具自动维护的)。
内容的提问来源于stack exchange,提问作者Bernard Darnton
相关产品推荐
相关产品推荐

