Imr*_*vel 4 c# .net-assembly roslyn c#-7.1
C# 7.1引入了一些新的命令行参数来帮助创建“参考程序集”。通过文档,它输出一个程序集,其中:
将它们的方法体替换为单个 throw null 体,但包括除匿名类型之外的所有成员。
我发现了一个有趣的注释,它在变化时更加稳定:
这意味着它的更改频率低于完整的程序集——许多常见的开发活动不会更改接口,只会更改实现。这意味着增量构建可以更快 - ...
我们将介绍第二个概念,即“参考组件”(也称为骨架组件)。[---]它们将用于构建场景。
.. 无论这些“构建场景”对于罗斯林来说是什么。
据我所知,对于普通的 .NET 程序集用户来说,此类程序集可能更小,并且加载反射的速度稍快。好的但是:
它的用处似乎相当小众。
因此,我想知道通用程序集生成器方面的事情 - 什么时候应该考虑显式使用这些新的编译器标志来创建引用程序集?除了罗斯林本身之外,它还有任何实际用途吗?
小智 5
此功能的动机确实是构建场景,但它们并不是 Roslyn 特有的;它们也是您的构建场景。
当您构建项目时,构建引擎 (MSBuild) 需要确定构建的每个输出是否相对于其输入是最新的。例如,如果您不更改任何内容,只是连续运行两次构建,则第二次不需要调用 C# 编译器:程序集已经正确。
参考程序集允许在更多场景中跳过程序集的编译步骤,因此您的构建速度可以更快。我认为一个例子有助于说明。
假设您有一个包含B.exe依赖于 的解决方案A.dll。
B 的编译器命令行看起来像
csc.exe /out:B.exe /r:..\A\bin\A.dll Program.cs
Run Code Online (Sandbox Code Playgroud)
它的输入是
Program.cs)如果更改 A 的源并构建解决方案,编译器必须为 A 运行,生成新的A.dll. 然后,由于A.dll是 B 编译的输入,因此 B 也必须重新编译。
使用 A 的参考组件会稍微改变这一点
csc.exe /out:B.exe /r:..\A\bin\ref\A.dll Program.cs
Run Code Online (Sandbox Code Playgroud)
A 的输入现在是其参考程序集,而不是其实现/正常程序集。
由于参考程序集比完整程序集小,因此它本身对构建时间的影响较小。但这还不足以证明此功能的合理性。重要的是编译器只关心传入引用的公共 API 表面。如果程序集的内部实现细节已更改,则无需重新编译引用它的程序集即可采用新行为。正如 @Hans Passant 在评论中提到的,这就是 .NET Framework 本身如何在未更改的用户代码上提供兼容的性能改进和错误修复。
参考程序集功能的好处来自于使用它们所做的 MSBuild 工作。假设您更改 A 中的内部实现细节,但不更改其公共接口。在下一个构建中,
A.dll(使用更改后的实现) 和ref\A.dll,这与之前的参考程序集相同。ref\A.dll与之前的输出相同,因此不会将其复制到 A 的输出文件夹。A.dll到其输出,并准备好以新行为运行。当您在大型解决方案中进行时,跳过下游编译的效果可能会更加复杂——更改注释{ProjectName}.Utilities.dll不再需要构建所有内容!
许多更改涉及更改公共 API 表面和内部实现,因此此更改不会加快所有构建的速度,但确实会加快许多构建的速度。