Roslyn编译:类型定义在未被引用的程序集中

4
我尝试使用Roslyn编译一些代码,但是出现了以下错误信息:
CS0012:类型“Func<,>”在未引用的程序集中定义。您必须添加对程序集“System.Runtime,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a”的引用。
我仍然对此消息感到困惑,因为 Func <,> 应该在 mscorelib 中而不是 System.Runtime 中。我已经搜索了这个错误并且只找到了一个热修复程序,应该会有所帮助,但实际上并没有。
是否有人遇到过与 .net 4.5.1 和最新版本的 Roslyn 相关的类似问题?
谢谢!

你为什么认为它不应该在System.Runtime中? - DavidG
@DavidG 这就是问题所在。请看我的回答。谢谢 :) - BendEg
3个回答

6

我最近也遇到了类似的问题。我添加了下面这行代码,解决了这个问题:

assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default

整个 CSharpCompilation 对象的初始化如下:
var compilation = CSharpCompilation.Create(
    assemblyName,
    new[] { syntaxTree },
    references,
    new CSharpCompilationOptions(
        OutputKind.DynamicallyLinkedLibrary,
        optimizationLevel: OptimizationLevel.Release,
        assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default));

你是我的英雄!我花了一整天的时间寻找,这是唯一接近可行的东西。 - gurrenm3

6

好的,找到了一个解决方案。看起来System.Runtime可能是问题所在(一开始我以为这是可移植库的问题)。

我需要使用以下代码片段:

 List<PortableExecutableReference> refs = new List<PortableExecutableReference>();
 refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "mscorlib.dll")));
 refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.dll")));
 refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Core.dll")));
 refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")));
 refs.Add(MetadataReference.CreateFromFile(Assembly.GetEntryAssembly().Location));

这是当前的正确解决方法。请注意,根据您从所引用的PCL中使用的API中提到的类型,您可能需要添加更多的门面引用而不仅仅是一个。 - Kevin Pilch

1
这里有两个相关的bug,一个在MSBuild目标中,另一个在Roslyn的MSBuildWorkspace中。当VS2015的MSBuild工具包的RTM版本和Roslyn的1.0版本发布时,它们都应该被修复。
通常情况下,如果通过"ImplicitlyExpandDesignTimeFacades"目标引用便携式类库,MSBuild会自动添加对System.Runtime和其余facade程序集的引用,但是对于MSBuildWorkspace来说,这个功能有问题。(注:截至2015年7月20日,此问题已得到解决。)
请参阅https://github.com/dotnet/roslyn/issues/2824以获取更多详细信息。

没关系。我刚意识到你正在手动构建编译,所以你应该自己添加门面。 - Kevin Pilch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接