前言

今天 .NET 官方博客宣布 C# 9 Source Generators 第一个预览版发布,这是一个用户已经喊了快 5 年特性,今天终于发布了。

简介

Source Generators 顾名思义代码生成器,它允许开发者在代码编译过程中获取查看用户代码并且生成新的 C# 代码参与编译过程,并且可以很好的与代码分析器集成提供 Intellisense、调试信息和报错信息,可以用它来做代码生成,因此也相当于是一个加强版本的编译时反射。

使用 Source Generators,可以做到这些事情:

  • 获取一个 Compilation 对象,这个对象表示了所有正在编译的用户代码,你可以从中获取 AST 和语义模型等信息

  • 可以向 Compilation 对象中插入新的代码,让编译器连同已有的用户代码一起编译

Source Generators 作为编译过程中的一个阶段执行:

编译运行 -> [分析源代码 -> 生成新代码] -> 将生成的新代码添加入编译过程 -> 编译继续。

上述流程中,中括号包括的内容即为 Source Generators 所参与的阶段和能做到的事情。

作用

.NET 明明具备运行时反射和动态 IL 织入功能,那这个 Source Generators 有什么用呢?

编译时反射 - 0 运行时开销

拿 ASP.NET Core 举例,启动一个 ASP.NET Core 应用时,首先会通过运行时反射来发现 Controllers、Services 等的类型定义,然后在请求管道中需要通过运行时反射获取其构造函数信息以便于进行依赖注入。然而运行时反射开销很大,即使缓存了类型签名,对于刚刚启动后的应用也无任何帮助作用,而且不利于做 AOT 编译。

Source Generators 将可以让 ASP.NET Core 所有的类型发现、依赖注入等在编译时就全部完成并编译到最终的程序集当中,最终做到 0 运行时反射使用,不仅利于 AOT 编译,而且运行时 0 开销。

除了上述作用之外,gRPC 等也可以利用此功能在编译时织入代码参与编译,不需要再利用任何的 MSBuild Task 做代码生成啦!

另外,甚至还可以读取 XML、JSON 直接生成 C# 代码参与编译,DTO 编写全自动化都是没问题的。

AOT 编译

Source Generators 的另一个作用是可以帮助消除 AOT 编译优化的主要障碍。

许多框架和库都大量使用反射,例如System.Text.Json、System.Text.RegularExpressions、ASP.NET Core 和 WPF 等等,它们在运行时从用户代码中发现类型。这些非常不利于 AOT 编译优化,因为为了使反射能够正常工作,必须将大量额外甚至可能不需要的类型元数据编译到最终的原生映像当中。

有了 Source Generators 之后,只需要做编译时代码生成便可以避免大部分的运行时反射的使用,让 AOT 编译优化工具能够更好的运行。

例子

INotifyPropertyChanged

写过 WPF 或 UWP 的都知道,在 ViewModel 中为了使属性变更可被发现,需要实现 INotifyPropertyChanged 接口,并且在每一个需要的属性的 setter 处除法属性更改事件:

当属性多了之后将会非常繁琐,先前 C# 引入了 CallerMemberName 用于简化属性较多时候的情况:

即,用 CallerMemberName 指示参数,在编译时自动填充调用方的成员名称。

但是还是不方便。

如今有了 Source Generators,我们可以在编译时生成代码做到这一点了。

为了实现 Source Generators,我们需要写个实现了 ISourceGenerator 并且标注了 Generator 的类型。

完整的 Source Generators 代码如下:

有了上述代码生成器之后,以后我们只需要这样写 ViewModel 就会自动生成通知接口的事件触发调用:

上述代码将会在编译时自动生成以下代码参与编译:

非常方便!

使用时,将 Source Generators 部分作为一个独立的 .NET Standard 2.0 程序集(暂时不支持 2.1),用以下方式引入到你的项目即可:

限制

Source Generators 仅能用于访问和生成代码,但是不能修改已有代码,这有一定原因是出于安全考量。

文档

Source Generators 处于早期预览阶段,docs.microsoft.com 上暂时没有相关文档,关于它的文档请访问在 roslyn 仓库中的文档:

设计文档

使用文档

后记

目前 Source Generators 仍处于非常早期的预览阶段,API 后期还可能会有很大的改动,因此现阶段不要用于生产。

另外,关于与 IDE 的集成、诊断信息、断点调试信息等的开发也在进行中,请期待后续的 preview 版本吧。

C# 9 新特性:代码生成器、编译时反射相关推荐

  1. .Net Framework 各个版本新特性总结 (一)

    .Net Framework 4.5 新特性 最近面试时又看到有问.Net Framework 新特性的问题,一时被问到了.平时也是拿起来就用,新版本出来了,新特性也就是瞄一眼,也没去仔细查看.这次干 ...

  2. C# 强大的新特性 Source Generator

    C# 强大的新特性 Source Generator Intro 微软在 .NET 5 中引入了 Source Generator 的新特性,利用 Source Generator 我们可以在应用编译 ...

  3. Java8的一些常用新特性

    Java8新特性 回顾: 1 反射:是类的解剖技术,把类中各个元素使用对象封装.属性.方法.构造方法 2 Class 是反射的起源 ,每个类都是Class的对象,而且只有一个(1)通过对象getCla ...

  4. iOS 版本更新提示、新特性启动页面思路 —— HERO博客

    简单整理iOS开发中,面对版本更新提示.新特性启动页面时的思考思路. 首先认清两者区别,版本更新的提示可能只要版本变动就会提示,需要重复提醒.而新特性页面可能只出现在比较大的版本更新中,通常只显示一次 ...

  5. 01-java基础加强,eclipse工具使用,快捷键,断点调试,单元测试,jdk5新特性,增强for循环,集合map,list,可变参数,枚举,反射,泛型

    一.eclipse工具的使用 1. java代码的位置 1) 选择工作空间 workspace  选择一个文件夹存放程序(代码) 不要用中文和空格 2) 新建一个java 工程(Project) 3) ...

  6. 反射、注解、动态代理、JDK8新特性

    反射.注解.动态代理.JDK8新特性 第一章.反射 1.类的加载 源文件--通过javac编译-->字节码文件---通过Java命令(通过ClassLoader)--->JVM运行字节码文 ...

  7. 简述systemd的新特性及unit常见类型分析、使用systemd管理编译安装的nginx

    1. systemd新特性 并行处理(同时启动)所有服务. 基于依赖关系定义的服务控制逻辑 系统状态快照 按需激活进程,只有第一次被访问时才会真正启动: 2. systemd的常见unit类型 Ser ...

  8. [Unity脚本运行时更新]C#7.2新特性

    洪流学堂,让你快人几步!本文首发于洪流学堂微信公众号. 本文是该系列<Unity脚本运行时更新带来了什么?>的第7篇. 洪流学堂公众号回复runtime,获取本系列所有文章. Unity2 ...

  9. [Unity脚本运行时更新]C#6新特性

    洪流学堂,让你快人几步!本文首发于洪流学堂微信公众号. 本文是该系列<Unity脚本运行时更新带来了什么?>的第4篇. 洪流学堂公众号回复runtime,获取本系列所有文章. Unity2 ...

最新文章

  1. 我国第一台微型计算机诞生于哪一年,2015计算机一级《MSOffice》章节练习题及答案(1)...
  2. 【 FPGA 】组合逻辑中的竞争与险象问题(二)
  3. 索赔 100 万!只是因为一个开源插件?
  4. legend3---2、网站的代码里面的/也是代表根目录
  5. Ubuntu 16.04 搭建Android开发环境
  6. Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能
  7. commons dbcp.jar有什么用
  8. 说说中国的图书出版业者-读《小学奥数举一反三(5年级A版)》和《2010注册建筑师建筑结构考试强化模拟试题集》有感...
  9. 技术在于精,其次在于多
  10. 华为承诺的鸿蒙系统兑现没有,华为鸿蒙系统遭截胡,安卓12系统率先出手
  11. 90后告别第一份工作后,更青睐新一线城市开启职场第二步
  12. 微信群活跃度测试软件,微信群怎么监控活跃度?
  13. 天气预报查询数据接口、实时天气、未来24小时、7天/15天预报
  14. android 卡片消息,安卓QNotified 支持xml卡片QQ消息 - 陌路人博客
  15. (转)工业机器人用什么语言编程的?
  16. 【优化】1338- 分享一下图像优化原理
  17. 教育心理学有一句名言
  18. 吉尼斯世界纪录线上化,最多人同时在线拆箱、最长时间视频直播挑战成功
  19. Event-Souring模式
  20. QT下载速度慢的解决方法

热门文章

  1. 显示学生各科成绩和总成绩-面试被问到
  2. IOS-网络(大文件下载)
  3. twitter api使用_使用P2创建自己的Twitter风格的组博客
  4. roku能不能安装软件_如何阻止假期更改Roku主题
  5. 如何搭建html运行环境,搭建真实的运行环境2019.4.22
  6. 接口文档神器Swagger(下篇)
  7. SQL Server Update 所有表的某一列(列名相同,类型相同)数值
  8. 构建微型数据中心——在laptop上运行Rancher
  9. Android开发之动画(转)
  10. GNU make manual 翻译(四十三)