注:我删除了大部分原来的回复。它回答了错误的问题。接下来是更好的回应。
啊,现在我明白你在问什么了:“安装 .NET 4.5 后,Visual Studio 2010 如何知道编译为 C# 4 而不是 C# 5,甚至 Visual Studio 2010 和 Visual Studio 2012 使用相同的 csc.exe 并通过相同的选项吗?”
@mletterle 但是 .NET 4.5 是 .NET 4 的就地升级。所以我的机器上实际上只有 .NET 4。唯一的可能性是 IDE 隐藏了我看不到的 .NET 4 编译器的隐藏副本。
我不确定你从哪里听说的,也不知道你为什么这么认为。 .NET 4.5 不是就地升级。这是该工具的不同版本。会有差异。这是其中之一。
更新1:
看起来我们使用了“就地”升级的不同定义。我对“就地”的用法是“版本之间不应有明显差异的升级”。中给出的定义您链接到的文章 http://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx以不同的方式使用它:“就地”的用法是“使用相同的 CLR,但添加新的库”。
由于 C# 5 与 C# 4 不同,因此在我熟悉的用法中该更改并未“就位”。
因此,区别不在于您所针对的 CLR,而在于您使用的语言版本 - CLR 是“就地”升级(均为 4.0 CLR),但语言不是(VS2010 中的 C# 4) ,VS2012 中的 C#5。)
更新2:
在 .csproj 文件(实际上是由 Visual Studio 管理的 msbuild 文件)中,有一个指定目标框架的属性。使用 Visual Studio 2012 制作的项目默认具有以下内容:
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
而 Visual Studio 2010 中针对版本 4 的项目如下所示:
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
这告诉 Visual Studio 在构建一个或另一个目标框架时设置环境。虽然看起来 csc.exe 是直接从命令提示符调用的,但实际上并非如此:msbuild 项目实际上正在处理,并且它发生在“Visual Studio”的自定义处理环境中。
我只能假设发生的情况的具体情况,但很可能在升级后,将“TargetFrameworkVersion”属性设置为 v4.0 会在编译针对 v4.0 的项目期间将环境返回到 v4.0。另一方面,通过在没有 msbuild 设置环境的情况下从命令行调用 csc.exe,它会使用其版本的“默认值”(现在默认为 C# 5),从而为您提供新的 C# 5 行为,即使您正在使用 VS 2010 命令提示符。不过,当您通过 MSBuild 调用构建时,它知道如何在构建期间返回原始 C# 4 环境(因为 MSBuild 也是 .NET 工具链的一部分。)