当前位置: 首页 > news >正文

c# 文件编译的过程

两次编译的过程:

整个流程的核心思路是:.NET 用两次编译把"写代码"和"跑代码"这两件事解耦开来。

第一次编译:源码 → IL(开发时完成)

你写的 C# 代码(.cs文件)通过csc.exe编译器,翻译成一种叫做IL(中间语言,Intermediate Language)的中间产物,最终打包成.exe.dll文件。这一步在你的开发机上完成,IL 不是机器码,任何 CPU 都还不能直接执行它。

VB.NET、F# 等语言也有自己的编译器,但最终都会生成同一种 IL,这就是 .NET 能做到"跨语言互调"的根本原因。

第二次编译:IL → 机器码(运行时完成)

当用户在自己的机器上运行这个.exe时,CLR(公共语言运行时)启动,其中的JIT(Just-In-Time,即时编译器)读取 IL,根据当前机器的 CPU 架构,即时翻译成真正的机器码(x86 / x64 / ARM 等),然后交给操作系统执行。

为什么要这样设计?

这个设计带来了两个核心好处:一是跨平台,同一份.dll文件可以在 Windows/Linux/macOS 上运行,由各平台的 CLR 负责翻译成对应机器码;二是跨语言,C# 和 VB.NET 可以互相调用对方的库,因为底层都是同一种 IL。

托管代码 vs 非托管代码

的区别,以及 CLR 到底帮你管了哪些事。

核心区别:有没有人管你

非托管代码(如 C++)写的程序,编译出来直接就是 CPU 机器指令,操作系统拿到就跑。好处是快、直接;坏处是所有事情都要程序员自己负责——内存要自己申请自己释放,忘了就内存泄漏,越界访问就直接崩溃,没有任何保护。

托管代码(C# 就是这类)写的程序,产物是 IL 中间语言,必须交给 CLR 来"代为管理",CLR 再翻译成机器码给操作系统执行。多了这一层,CLR 就能替你做很多事:

CLR 替你管的六件事:

  • JIT 编译:把 IL 实时翻译成当前机器的机器码,上一篇讲的第二次编译就在这里发生
  • 内存管理:你用new创建对象,CLR 自动在堆上给你分配空间,不用手动malloc
  • 垃圾清理(GC):你不再用的对象,GC 会自动回收内存,彻底告别内存泄漏
  • 异常处理:程序出错时有统一的try/catch机制兜底,不会直接崩给用户看
  • 类加载器:程序集(dll)按需加载,用到哪个加载哪个,不用手动管理
  • 反射:程序运行时可以动态查询"这个类有哪些方法、属性",WPF 的数据绑定底层就大量依赖反射

对学 C# 的你意味着什么

你写的每一行 C# 代码都是托管代码,受 CLR 保护。这意味着你几乎不需要关心内存管理,不会因为忘记释放内存而崩溃,异常会被妥善捕获。代价是相比 C++ 有一点点性能开销,但对于桌面应用(WPF)来说完全可以忽略不计。

CLR CTS CLS

三者是层层包含的关系,从大到小:CLR ⊃ CTS ⊃ CLS。

CLR(公共语言运行时)是最大的那层,是整个 .NET 的"运行环境",就像前两张图讲的虚拟机。它负责 JIT 编译、垃圾回收、异常处理等所有运行时工作。CTS 和 CLS 都是 CLR 的组成部分。

CTS(通用类型系统)住在 CLR 里面,它回答的问题是:"不同语言(C#、VB.NET、F#)之间,类型怎么统一?" CTS 规定了 .NET 平台上所有合法类型的定义规则,比如什么是类、什么是结构体、什么是接口、值类型和引用类型怎么区分。有了 CTS,C# 的int和 VB.NET 的Integer才能被认定为同一个底层类型(System.Int32),两种语言的代码才能互相传递数据。

CLS(公共语言规范)是 CTS 的一个子集,是更小的那一层。它回答的是:"如果我想写一个库,让所有 .NET 语言都能调用,我必须遵守哪些规则?" CLS 是各语言之间的"最小公约数"。举个例子,C# 支持无符号整数uint,但 VB.NET 不支持,所以uint不在 CLS 里。你写的公共库如果用了uint作为公开接口,VB.NET 的用户就无法使用它。


用一句话概括三者的分工:CLR 负责跑程序,CTS 负责统一类型,CLS 负责跨语言互通。对你学 C# 和 WPF 而言,实际编码时不需要刻意操作这三者,但理解它们能帮你看懂很多"为什么 .NET 这样设计"的问题。

http://www.jsqmd.com/news/630351/

相关文章:

  • 从千卡集群到边缘端部署,全栈性能基线如何统一?,详解开源Benchmarking Suite v3.0的12项可复现指标设计
  • VMware虚拟机版本兼容性问题:手动修改vmx和vmdk文件实战指南
  • 大模型上线不再踩坑(SITS2026工程化红线全景图)
  • macOS权限配置:3步解决BongoCat键盘输入无响应问题
  • 5个SRWE窗口分辨率控制技巧:突破游戏与应用限制的终极方案
  • 大模型推理功耗太高?揭秘GPU利用率不足42%的真相及5步精准调优法
  • 电商客服+导购智能体的设计与开发子
  • 龙芯k - 走马观碑组VLLX驱动移植系
  • 基于遗传算法优化的BP神经网络多输入双输出预测模型技术说明
  • 兰亭妙微商业化设计白皮书:四大变现模式、视觉赋能策略与GSM价值量化模型 - ui设计公司兰亭妙微
  • 如何在Java中调用Oracle的包体Package方法_调用语法的格式与参数绑定机制
  • LangChain4j简介以及快速入门
  • 别再乱选电源了!手把手教你区分LDO、BUCK和电荷泵,选对效率翻倍
  • Cursor VIP共享方案技术指南:免费解锁AI编程助手完整教程
  • SITS2026 vs ISO/IEC 42001 vs ML Ops 1.2:三大标准对比表+企业适配决策树(含金融/医疗/政务行业特供版)
  • Xcode免证书真机调试实战指南
  • JDK1.8环境下的S2-Pro Java客户端开发与性能调优
  • PCBA FCT生产测试设备简介
  • 世界第一个开源可商用 .NET Office 转 PDF 工具/库 - MiniPdf僬
  • 【GPT-4级模型轻量化权威指南】:基于华为昇腾+NVIDIA Triton的混合剪枝框架,推理延迟直降63%
  • 深度学习图像拼接新突破:USID++如何实现无监督大视差场景下的精准对齐
  • FastAPI项目半夜报警吵醒你?聊聊告警这事儿怎么搞!乃
  • JBI投稿系统深度体验:除了研究创新,这些表单细节才是编辑的第一印象
  • Wan2.2-I2V-A14B效果实测:运动物体(飞鸟/车流/水流)轨迹自然度评分92.6
  • 2026奇点大会核心成果首发(仅限首批读者):基于MoE-LLM的实时摘要生成架构白皮书
  • 轴承二维与三维有限元模型及其ANSYS仿真计算准备:轻松上手学习资源
  • 深夜告警炸裂?这份Linux故障排查“作战地图”请收好曰
  • 从LED闪烁到继电器驱动:手把手用Arduino玩转NPN/PNP三极管开关电路(附代码)
  • 为什么你的大模型越训越偏?SITS2026披露持续预训练中被忽视的2类隐性灾难性遗忘
  • Geo-SAM:地理空间智能分割解决方案与实时遥感分析技术革命