【发布时间】:2018-04-28 04:14:39
【问题描述】:
在大多数(如果不是全部)C#(以及 F# 和 VB)库和在 Visual Studio 中创建的可执行项目中,都有一个自动添加的 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
.csproj 文件确实指定了目标框架,我猜这是在构建期间将目标传递给编译器的地方。
如果没有配置文件中的<startup> 部分,可执行文件似乎运行得很好。 The documentation 解释了 什么 属性是什么意思,但是,多年来看到它们,我一直不明白 为什么 在配置文件中需要它们。不过,我主要处理的是 Windows 桌面应用程序。
This answer 明确指出“使编译为目标 .NET 4.0 的程序表现得像在更高版本上运行是不可能的”,相反,如果在较低版本上运行程序,我会感到非常惊讶框架也是可以的。
那么,在什么场景下,应用程序开发者需要在应用程序的.config文件中指定运行时的版本和TFM,是否必须总是复制编译器硬编码到二进制文件中的信息?乍一看,这个要求似乎违反直觉。
2018-06-29 更新:X-ref:我要求澄清 GitHub 问题 dotnet/docs#6234 中的文档。
【问题讨论】:
-
对我来说,设计似乎是“为未来保留一些东西”。硬编码到二进制文件中的信息是不可能更改的,但有时 Microsoft 可能需要向开发人员提供一种更改运行时行为的方法(我无法说出具体案例,但运行时版本相关的行为在 .NET Framework 中很常见),其中他们可以简单地修改
app.config中的 SKU(在这种情况下,两者不再重复)。