在 Visual Studio 中创建的大多数(如果不是全部)C#(以及 F# 和 VB)库和可执行项目中,都会自动添加app.config
指定运行时版本和目标框架名称 (TFM) 的文件:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
. . .
即使缺席app.config
文件完全,编译器似乎总是生成一个程序集级属性,如 ILDASM 所示:
.custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 // ....NETFramework
.. // ,Version=v4.6.1.
bytes snipped-> .. // .T..FrameworkDis
.. // playName..NET Fr
61 ) // amework 4.6.1
The .csproj
文件确实指定了目标框架,我猜这是在构建过程中目标从编译器传递到编译器的地方。
可执行文件似乎运行得很好,没有<startup>
配置文件中的部分。文档 https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element解释what这些属性是什么意思,但是,看了很多年,我一直不明白why配置文件中需要它们。不过,我主要处理的是 Windows 桌面应用程序。
这个答案 https://stackoverflow.com/a/38036555/1149924明确指出“不可能让编译为目标 .NET 4.0 的程序表现得像在更高版本上运行一样”,相反,如果也可以在较低版本的框架上运行程序,我会感到非常惊讶。
那么,在什么场景下应用开发者需要在应用程序中指定运行时的版本和TFM呢?.config
应用程序的文件,它是否必须始终复制由编译器硬编码到二进制文件中的信息?乍一看,这个要求似乎违反直觉。
更新 2018-06-29:X-ref:我要求对 GitHub 问题中的文档进行澄清点网/文档#6234 https://github.com/dotnet/docs/issues/6234.