我在.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;
但是,当我以.NET 4.5.x为目标时,此代码无法编译(正如人们所期望的那样)。
这里让我感到困惑的是,考虑到.NET 4.7是.NET 4.5的就地更新(即安装.NET 4.7时,.NET的System.dll
4.5替换为.NET 4.7)。
编译器如何知道我不能在.NET 4.5上使用SystemDefault
但可以在4.7上使用它?这是通过编译器已知的某种API文件完成的吗?
事实:当我定位.NET 4.5并安装了.NET 4.7时,对
Enum.GetValues(typeof(SecurityProtocolType)
的调用会给我SecurityProtocolType.SystemDefault
。所以我很确定我的.NET 4.5应用程序使用.NET 4.7System.dll
。
答案 0 :(得分:6)
编译器如何知道我不能在.NET 4.5上使用SystemDefault但可以在4.7上使用它?这是通过编译器已知的某种API文件完成的吗?
是的,我希望通过参考程序集来完成。引用程序集是一个有效地仅包含可访问的API定义的程序集。
在我的Windows计算机上,这些文件位于C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework
答案 1 :(得分:5)
指定.NET Framework 4.5的目标时,您将指定该API的接口表面。编译器使用此精确版本来确定可用的类型。
当目标计算机上存在.NET Framework 4.7运行时时,类型将从4.5转发到4.7。但这只是运行时行为。在编译应用程序时,它不会改变目标是.NET Framework 4.5的事实。请记住,在目标计算机上部署程序集时,它已编译为中间语言。编译器在运行时根本不涉及,因此无法动态更改目标框架。
至于你的事实,那就是Reflection的运行时行为,因为它使用的运行时框架是4.7。