谁知道.net framework 是怎么实现向上兼容的吗?

2023-01-10 10:41:49 +08:00
 bthulu

比如.net4.6.2, 支持 C#7.0. 但实际上你把语言级别提升到 8.0, 就能使用 8.0 的新特性了, 编译出来的 exe 也能在仅安装了.net4.6.2 的电脑上使用. 感觉就很神奇, .net4.6.2 是怎么知道并成功编译.net4.7 甚至.net4.8 添加的新特性的?

2873 次点击
所在节点    .NET
19 条回复
thinkershare
2023-01-10 10:45:40 +08:00
因为 C#和.NET Framework 并没有严格的版本捆绑,但是 BCL 的一些特性是需要 Runtime(CLR)支持的,这种情况下,你就会发现程序跑起来就会挂掉。说白了,语言很多时候升级的只是语法糖,不需要 Runtime 支持,这种情况就无所谓,只要编译器编译后的 IL 在旧的 Runtime 上能跑,就没啥问题。另外每个新的版本的 Framework 都有自己新增强的 API ,这种情况你会发下也跑不起。
thinkershare
2023-01-10 10:50:41 +08:00
举个例子,你使用.NET 6 作为 SDK, 语言版本是可以选择: 6/7/8/9/10/11 的,甚至可以选择 latest ,SDK 只是限制了你使用的 APIs 的数量。但部分需要 runtime 支持的新语法特性是无法通过编译的。.NET 发展了 20 年,MSIL 的变化是非常非常少的。
urnoob
2023-01-10 11:05:09 +08:00
写代码:语法可以玩出花
编译后:字节码万年不变
bthulu
2023-01-10 11:07:00 +08:00
@thinkershare 你这个只能说明最新的 SDK 支持旧的语言版本, 无法解释旧的 SDK 是怎么支持新的语言版本的.
我知道很多特性只是语法糖, 但是旧版本的 SDK 他是怎么知道新的语法糖是咋样的并且能编译成旧的语法形式?
kanezeng
2023-01-10 11:19:26 +08:00
@bthulu 整理一下啊,编译的时候是 SDK ,通过编译成 IL 之后,运行的时候 Runtime 跑 IL 。

如果你用到的新版本特性只是语法糖,说白了只是代码不同,编译的时候智能用新版本的 SDK ,它会把含语法糖的代码编译成 IL ,编译后的 IL 和你用老版本语法不用语法糖的其实是一样的,所以你拿哪个版本的 Runtime 来跑这个 IL 都可以,因为他们本质上都是一样的 IL 。

如果你用到的新版本的特性是需要新版本的 Runtime 支持的,那么如果你用老版本的 runtime 就跑不起来了。
Asvel
2023-01-10 11:29:35 +08:00
因为你用的其实是新版本的工具链,只是告诉它去生成用于 .net4.6.2 环境的编译产物,新版本的工具链自然能认识新版本的特性。
geelaw
2023-01-10 11:44:21 +08:00
@bthulu #4 你的说法令我感到很迷惑,如果 csc 可以编译 C# 8.0 的代码,说明 SDK 支持 C# 8.0 ,跟 .NET 4.6.2 “支持不支持” C# 8.0 没有任何关系——实际上后面这句话“错误都不是”,因为不存在某个版本的 .NET 支持 C# 的概念,C# 不过是众多可以编译成 IL 的语言之一。至于新版的 SDK 可以编译出旧版运行时库可以跑的程序,这实在是太常见了。
thinkershare
2023-01-10 12:30:59 +08:00
@bthulu 使用.NET 4.6.1 自带的编译器编译 C# 8.0 的很多语法是编译通不过的。语言版本号,只是告诉编译器你当前要使用的语言的版本规范,因为语言升级有时候是破坏性修改。.NET 6.0 SDK 携带的 C#编译器是支持 C#11-C#1.0 所有版本的,C#4/C#5 这种同样代码编译后的 IL 并不是完全一致的,也就是发生了破坏性改变。
bthulu
2023-01-10 12:44:28 +08:00
@thinkershare
@geelaw
问题就是我用的.net4.6.2 的 sdk 编译了含有 C#8.0 语法特性的源码.
我当然知道高版本的 SDK 可以随意编译低语言版本, 但我问的一直都是低版本的 SDK 是怎么编译高语言版本的源码的.
yolee599
2023-01-10 12:52:43 +08:00
变的只是语法,编译出来的东西不会变
janxin
2023-01-10 13:06:40 +08:00
net framework 有向上兼容性保证吗?应该没有吧
thinkershare
2023-01-10 13:12:27 +08:00
@bthulu 谁告诉你可以的?
thinkershare
2023-01-10 13:24:57 +08:00
@bthulu 你自己调用 csc.exe 前请自己检测自己的编译器版本,例如:Microsoft (R) Visual C# Compiler version 4.8.9032.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240
fighte97
2023-01-10 15:41:36 +08:00
比如 Unity2017 里是无法写属性默认值 本地函数等等 会提示你使用更高版本的 C#
hez2010
2023-01-10 22:49:36 +08:00
做个类比就是一个语言再怎么更新,编译器编译出来的汇编语言是不会变的。这里的汇编对于 .net 来说就是 IL ,C# 再怎么更新最后都是编译到 IL ,只要 IL 本身没有引入破坏性更改就能一直兼容下去。
mmdsun
2023-01-11 12:34:56 +08:00
我也是这么用的之前.net 4.7 ,官网只能最高支持 C#8 。我在项目里面改成 C#9 并且用 C#9.0 的语法也没问题。
thinkershare
2023-01-11 19:37:15 +08:00
@mmdsun 这是因为你用的并不是.NET Framework 4.7 SDK 的 csc.exe 编译的代码,否则你马上就会发现一堆错误。因为你使用了开发机器上的 Visual Studio 集成的.NET 的 csc 编译器,那个一般都非常新,所以才能编译通过,如果你手动调用.NET Framework 4.7 的 csc.exe 编译,C# 6 的很多语法都会直接编译报错。
noreplay
2023-01-17 08:38:53 +08:00
好像是用 roslyn 编译的代码
nebkad
2023-01-24 15:41:01 +08:00
因为 CIL (旧称 MSIL ) Common Intermediate Language 通用中间语言
.net runtime 不认识 C# F# VB 等等的语言, 只认识 CIL
高版本 C# 或者 SDK ,最终都要编译成 CIL ,所以你说的所谓“向上兼容” 并不存在,它一直都是那个 CIL 语言规范。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/907833

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX