比如.net4.6.2, 支持 C#7.0. 但实际上你把语言级别提升到 8.0, 就能使用 8.0 的新特性了, 编译出来的 exe 也能在仅安装了.net4.6.2 的电脑上使用. 感觉就很神奇, .net4.6.2 是怎么知道并成功编译.net4.7 甚至.net4.8 添加的新特性的?
1
thinkershare 2023-01-10 10:45:40 +08:00
因为 C#和.NET Framework 并没有严格的版本捆绑,但是 BCL 的一些特性是需要 Runtime(CLR)支持的,这种情况下,你就会发现程序跑起来就会挂掉。说白了,语言很多时候升级的只是语法糖,不需要 Runtime 支持,这种情况就无所谓,只要编译器编译后的 IL 在旧的 Runtime 上能跑,就没啥问题。另外每个新的版本的 Framework 都有自己新增强的 API ,这种情况你会发下也跑不起。
|
2
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 的变化是非常非常少的。
|
3
urnoob 2023-01-10 11:05:09 +08:00 1
写代码:语法可以玩出花
编译后:字节码万年不变 |
4
bthulu OP @thinkershare 你这个只能说明最新的 SDK 支持旧的语言版本, 无法解释旧的 SDK 是怎么支持新的语言版本的.
我知道很多特性只是语法糖, 但是旧版本的 SDK 他是怎么知道新的语法糖是咋样的并且能编译成旧的语法形式? |
5
kanezeng 2023-01-10 11:19:26 +08:00
@bthulu 整理一下啊,编译的时候是 SDK ,通过编译成 IL 之后,运行的时候 Runtime 跑 IL 。
如果你用到的新版本特性只是语法糖,说白了只是代码不同,编译的时候智能用新版本的 SDK ,它会把含语法糖的代码编译成 IL ,编译后的 IL 和你用老版本语法不用语法糖的其实是一样的,所以你拿哪个版本的 Runtime 来跑这个 IL 都可以,因为他们本质上都是一样的 IL 。 如果你用到的新版本的特性是需要新版本的 Runtime 支持的,那么如果你用老版本的 runtime 就跑不起来了。 |
6
Asvel 2023-01-10 11:29:35 +08:00
因为你用的其实是新版本的工具链,只是告诉它去生成用于 .net4.6.2 环境的编译产物,新版本的工具链自然能认识新版本的特性。
|
7
geelaw 2023-01-10 11:44:21 +08:00 1
@bthulu #4 你的说法令我感到很迷惑,如果 csc 可以编译 C# 8.0 的代码,说明 SDK 支持 C# 8.0 ,跟 .NET 4.6.2 “支持不支持” C# 8.0 没有任何关系——实际上后面这句话“错误都不是”,因为不存在某个版本的 .NET 支持 C# 的概念,C# 不过是众多可以编译成 IL 的语言之一。至于新版的 SDK 可以编译出旧版运行时库可以跑的程序,这实在是太常见了。
|
8
thinkershare 2023-01-10 12:30:59 +08:00
|
9
bthulu OP @thinkershare
@geelaw 问题就是我用的.net4.6.2 的 sdk 编译了含有 C#8.0 语法特性的源码. 我当然知道高版本的 SDK 可以随意编译低语言版本, 但我问的一直都是低版本的 SDK 是怎么编译高语言版本的源码的. |
10
yolee599 2023-01-10 12:52:43 +08:00 via Android
变的只是语法,编译出来的东西不会变
|
11
janxin 2023-01-10 13:06:40 +08:00
net framework 有向上兼容性保证吗?应该没有吧
|
12
thinkershare 2023-01-10 13:12:27 +08:00
@bthulu 谁告诉你可以的?
|
13
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 |
14
fighte97 2023-01-10 15:41:36 +08:00
比如 Unity2017 里是无法写属性默认值 本地函数等等 会提示你使用更高版本的 C#
|
15
hez2010 2023-01-10 22:49:36 +08:00 via Android
做个类比就是一个语言再怎么更新,编译器编译出来的汇编语言是不会变的。这里的汇编对于 .net 来说就是 IL ,C# 再怎么更新最后都是编译到 IL ,只要 IL 本身没有引入破坏性更改就能一直兼容下去。
|
16
mmdsun 2023-01-11 12:34:56 +08:00 via iPhone
我也是这么用的之前.net 4.7 ,官网只能最高支持 C#8 。我在项目里面改成 C#9 并且用 C#9.0 的语法也没问题。
|
17
thinkershare 2023-01-11 19:37:15 +08:00 3
@mmdsun 这是因为你用的并不是.NET Framework 4.7 SDK 的 csc.exe 编译的代码,否则你马上就会发现一堆错误。因为你使用了开发机器上的 Visual Studio 集成的.NET 的 csc 编译器,那个一般都非常新,所以才能编译通过,如果你手动调用.NET Framework 4.7 的 csc.exe 编译,C# 6 的很多语法都会直接编译报错。
|
18
noreplay 2023-01-17 08:38:53 +08:00 via Android
好像是用 roslyn 编译的代码
|
19
nebkad 2023-01-24 15:41:01 +08:00
因为 CIL (旧称 MSIL ) Common Intermediate Language 通用中间语言
.net runtime 不认识 C# F# VB 等等的语言, 只认识 CIL 高版本 C# 或者 SDK ,最终都要编译成 CIL ,所以你说的所谓“向上兼容” 并不存在,它一直都是那个 CIL 语言规范。 |