谁知道.net framework 是怎么实现向上兼容的吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bthulu
V2EX    .NET

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

  •  
  •   bthulu 2023-01-10 10:41:49 +08:00 3457 次点击
    这是一个创建于 1072 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    19 条回复    2023-01-24 15:41:01 +08:00
    thinkershare
        1
    thinkershare  
       2023-01-10 10:45:40 +08:00
    因为 C#和.NET Framework 并没有严格的版本捆绑,但是 BCL 的一些特性是需要 Runtime(CLR)支持的,这种情况下,你就会发现程序跑起来就会挂掉。说白了,语言很多时候升级的只是语法糖,不需要 Runtime 支持,这种情况就无所谓,只要编译器编译后的 IL 在旧的 Runtime 上能跑,就没啥问题。另外每个新的版本的 Framework 都有自己新增强的 API ,这种情况你会发下也跑不起。
    thinkershare
        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 的变化是非常非常少的。
    urnoob
        3
    urnoob  
       2023-01-10 11:05:09 +08:00   1
    写代码:语法可以玩出花
    编译后:字节码万年不变
    bthulu
        4
    bthulu  
    OP
       2023-01-10 11:07:00 +08:00
    @thinkershare 你这个只能说明最新的 SDK 支持旧的语言版本, 无法解释旧的 SDK 是怎么支持新的语言版本的.
    我知道很多特性只是语法糖, 但是旧版本的 SDK 他是怎么知道新的语法糖是咋样的并且能编译成旧的语法形式?
    kanezeng
        5
    kanezeng  
       2023-01-10 11:19:26 +08:00
    @bthulu 整理一下啊,编译的时候是 SDK ,通过编译成 IL 之后,运行的时候 Runtime 跑 IL 。

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

    如果你用到的新版本的特性是需要新版本的 Runtime 支持的,那么如果你用老版本的 runtime 就跑不起来了。
    Asvel
        6
    Asvel  
       2023-01-10 11:29:35 +08:00
    因为你用的其实是新版本的工具链,只是告诉它去生成用于 .net4.6.2 环境的编译产物,新版本的工具链自然能认识新版本的特性。
    geelaw
        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 可以编译出旧版运行时库可以跑的程序,这实在是太常见了。
    thinkershare
        8
    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
        9
    bthulu  
    OP
       2023-01-10 12:44:28 +08:00
    @thinkershare
    @geelaw
    问题就是我用的.net4.6.2 的 sdk 编译了含有 C#8.0 语法特性的源码.
    我当然知道高版本的 SDK 可以随意编译低语言版本, 但我问的一直都是低版本的 SDK 是怎么编译高语言版本的源码的.
    yolee599
        10
    yolee599  
       2023-01-10 12:52:43 +08:00 via Android
    变的只是语法,编译出来的东西不会变
    janxin
        11
    janxin  
       2023-01-10 13:06:40 +08:00
    net framework 有向上兼容性保证吗?应该没有吧
    thinkershare
        12
    thinkershare  
       2023-01-10 13:12:27 +08:00
    @bthulu 谁告诉你可以的?
    thinkershare
        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
    fighte97
        14
    fighte97  
       2023-01-10 15:41:36 +08:00
    比如 Unity2017 里是无法写属性默认值 本地函数等等 会提示你使用更高版本的 C#
    hez2010
        15
    hez2010  
       2023-01-10 22:49:36 +08:00 via Android
    做个类比就是一个语言再怎么更新,编译器编译出来的汇编语言是不会变的。这里的汇编对于 .net 来说就是 IL ,C# 再怎么更新最后都是编译到 IL ,只要 IL 本身没有引入破坏性更改就能一直兼容下去。
    mmdsun
        16
    mmdsun  
       2023-01-11 12:34:56 +08:00 via iPhone
    我也是这么用的之前.net 4.7 ,官网只能最高支持 C#8 。我在项目里面改成 C#9 并且用 C#9.0 的语法也没问题。
    thinkershare
        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 的很多语法都会直接编译报错。
    noreplay
        18
    noreplay  
       2023-01-17 08:38:53 +08:00 via Android
    好像是用 roslyn 编译的代码
    nebkad
        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 语言规范。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5422 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 06:37 PVG 14:37 LAX 22:37 JFK 01:37
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86