.NET目标框架兼容性和编译器 - 在.NET 4.5或更高版本上

Seb*_*ski 7 .net c# compilation

我在.NET开发方面经验丰富,但今天我被迫围绕以前从未想过的事情:

安装的.NET Framework,Visual Studio中的.NET Framework目标和C#编译器如何协同工作?

具体示例:System.dll包含枚举System.Net.SecurityProtocolType.在.NET 4.5此枚举包含成员SSl3,Tls,Tls11,和Tls12.使用.NET 4.7,SystemDefault添加了成员.

因此,针对.NET 4.7.x,此代码编译良好:

var p = SecurityProtocolType.SystemDefault;
Run Code Online (Sandbox Code Playgroud)

但是,当我以.NET 4.5.x为目标时,此代码无法编译(正如人们所期望的那样).

令我困惑的是,考虑到.NET 4.7是.NET 4.5 的就地更新(即在安装.NET 4.7时,System.dll.NET 4.5被.NET 4.7替换),这就是为什么这样做的原因.

编译器如何知道我不能SystemDefault在.NET 4.5上使用但可以在4.7上使用它?这是通过编译器已知的某种API文件完成的吗?

事实:当我以.NET 4.5为目标并安装了.NET 4.7时,Enum.GetValues(typeof(SecurityProtocolType)会给我一个电话SecurityProtocolType.SystemDefault.所以我很确定我的.NET 4.5应用程序使用的是.NET 4.7 System.dll.

Jon*_*eet 6

编译器如何知道我不能在.NET 4.5上使用SystemDefault但可以在4.7上使用它?这是通过编译器已知的某种API文件完成的吗?

是的,我希望它可以通过参考组件完成.引用程序集是一个有效地仅包含可访问的API定义的程序集.

在我的Windows机器上,这些都在 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework


Nig*_*888 5

指定.NET Framework 4.5的目标时,您将指定该API 的接口表面.编译器使用此精确版本来确定可用的类型.

当目标计算机上存在.NET Framework 4.7运行时时,类型将从4.5转发到4.7.但这只是运行时行为.在编译应用程序时,它不会改变目标是.NET Framework 4.5的事实.请记住,当程序集部署在目标计算机上时,它已经编译为中间语言.编译器在运行时根本不涉及,因此无法动态更改目标框架.

至于你的事实,那就是Reflection 的运行时行为,因为它使用的运行时框架是4.7.