V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bthulu
V2EX  ›  .NET

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

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

    比如.net4.6.2, 支持 C#7.0. 但实际上你把语言级别提升到 8.0, 就能使用 8.0 的新特性了, 编译出来的 exe 也能在仅安装了.net4.6.2 的电脑上使用. 感觉就很神奇, .net4.6.2 是怎么知道并成功编译.net4.7 甚至.net4.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   ·   实用小工具   ·   5455 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 08:40 · PVG 16:40 · LAX 00:40 · JFK 03:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.