抽丝剥茧!Source Generators原理讲解

前言

前段时间,我们已经用Source Generators实现了好多功能,比如AutoMapper、API最佳实践。

你看完那些实现代码,是不是还有点云里雾里!

Source Generators到底是怎么做到的?

基础知识

Source Generators是编译过程的一部分,它以编译树作为输入,通过分析代码,动态生成文件并把它们加入到编译过程中:

需要注意的是,你只能添加一些东西到代码,但不能改变现有的代码。

为了使用Source Generators,你必须创建.Net Standard项目,并引用nuget包Microsoft.CodeAnalysis.CSharp 3.8.0或以上版本。

基本的实现代码如下,你必须实现ISourceGenerator接口,并且用GeneratorAttribute标注:

[Generator]
public class DemoSourceGenerator : ISourceGenerator
{public void Execute(GeneratorExecutionContext context){throw new NotImplementedException();}public void Initialize(GeneratorInitializationContext context){throw new NotImplementedException();}
}

生成器执行上下文

主要生成过程通过Execute方法执行。

Execute传递一个GeneratorExecutionContext实例,下列是实例常用的属性和方法:

  • AdditionalFiles 获取当前编译项目文件中的所有AdditionalFiles标签

  • Compilation 编译上下文,最重要的对象

  • AddSource 向编译器加入代码,最重要的方法

语法树

通过GeneratorExecutionContext.Compilation我们可以获得编译上下文,有了这个对象,你就可以访问当前编译项目的整个语法树(SyntaxTree)。

那什么是语法树呢?

首先,安装.NET Compiler Platform SDK

然后,在VS中打开“视图”->“其他窗口”->“Syntax Visualizer”。

可以看到,语法树是一个树形结构,和每一行代码一一对应

语法树包含三种类型的项——node、token和trivia。

比如public class Class1 { }整体是ClassDeclaration node,下级的Class1则是ClassKeyword token, 而紧跟的空格则是Whitespace trivia

因此,只要我们遍历语法树,即可拿到编译中的任何代码。

Demo

现在把上面的综合起来,我们就可以开发Source Generators功能了:

public void Execute(GeneratorExecutionContext context)
{//获取第一个附加文件内容,用作代码模板var template = context.AdditionalFiles.First().GetText().ToString();//获取第一个类名var className = context.Compilation.SyntaxTrees.SelectMany(p => p.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>()).First().Identifier.Text;// 替换文本生成代码// 你也可以使用模板引擎或者StringBuilder拼接出代码var source = template.Replace("{Class}", className);// 向编译过程添加代码文件context.AddSource("Demo", SourceText.From(source, Encoding.UTF8));
}

在待编译的项目中添加一个附加文件

<ItemGroup><AdditionalFiles Include="template.txt"  />
</ItemGroup>

template.txt的文件内容如下:

using System;namespace ClassLibrary1
{public static class Demo{public static void SayHello(){Console.WriteLine("Hello {Class}!");}}
}

编译后,可以看到生成如下代码:

结论

希望我已经描述清楚了使用Source Generators的整个过程。

期待你用它开发出更多更好的功能!

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python跟java 效率_Python和Java该如何选择?老男孩Python人工智能

编程是很多人都想要掌握的技术&#xff0c;但是在行业之中编程语言有很多种&#xff0c;每个人的爱好&#xff0c;想要从事领域不同&#xff0c;自然选择也是不同&#xff0c;比较常见的编程语言就是Python和Java&#xff0c;那么对于这两种语言选择哪个好? 老男孩教育在这里为…

GPON技术概述

GPON技术转载自《电子发烧友》。文章链接请见&#xff1a;http://www.elecfans.com/article/88/171/2009/2009050556028.htmlGPON技术详述介绍GPON 技术之前&#xff0c;先介绍目前也被应用的另一种PON 技术“EPON”。1&#xff0e;EPON技术介绍EPON 又名 GEPON&#xff0c;是由…

linux中断处理汇编入口,Linux中断处理体系结构分析(一)

中断也是一种异常&#xff0c;之所以把它单独的列出来&#xff0c;是因为中断的处理与具体的开发板密切相关&#xff0c;除一些必须、共用的中断(比如系统时钟中断、片内外设UART中断)外&#xff0c;必须由驱动开发者提供处理函数。内核提炼出中断处理的共性&#xff0c;搭建一…

IOS开发学习的有用链接

iOS学习之 plist文件的读写

[转]C/C++ 文件读写操作总结

在编程的过程中&#xff0c;文件的操作是一个经常用到的问题&#xff0c;在CBuilder中&#xff0c;可以使用多种方法对文件操作&#xff0c;下面我就按以下几个部分对此作详细介绍&#xff0c;就是&#xff1a; 1、基于C的文件操作&#xff1b; 2、基于C的文件操作&#xff1b;…

没有违反GPL,他们真的给了源码

文 | Travis出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;【前情回顾】国内智能设备制造商 UMIDIGI 因违反 GPLv2 协议引发争议&#xff0c;并告知开发者“想要源码上门自取”。而后&#xff0c;知名科技博主 Naomi Wu&#xff08;机械妖姬&#xff09…

有朋友问我为什么这么帅

1 2 重庆的朋友告诉我这是微辣3 我就说我只是虚胖&#xff0c;这下你相信了吧&#xff1f;4 这明明就是打情骂俏好嘛5 这还是那个平常瓶盖都拧不开的女孩子吗6 被一个机器人撩到了&#xff01;7 这是什么原理&#xff1f;你点的每个赞&#xff0c;我都认真当成了喜欢

python安装详细步骤mac_Mac安装python3的方法步骤

Python有两个版本&#xff0c;一个是2.x版&#xff0c;一个是3.x版&#xff0c;这两个版本是不兼容的。 现在 Mac 上默认安装的 python 版本为 2.7 版本&#xff0c;若 安装 新版本需要 通过 该地址进行下载&#xff1a; https://www.python.org/ftp/python/3.5.0/python-3.5.0…

在Excel中实现下拉列表选择录入

我们在用Excel录入表格数据时&#xff0c;常常会遇到某列数据的值只在几个固定值中选择一个的情况&#xff0c;比如&#xff1a;人的性别列只可能录入男或女&#xff0c;对学历列只可能录入高中、大专、本科、研究生之一等。遇到这类数据&#xff0c;如果我们手工录入&#xff…

二叉搜索树python,代表python中的二叉搜索树

how do i represent binary search trees in python?解决方案class Node(object):def __init__(self, payload):self.payload payloadself.left self.right 0# this concludes the "how to represent" asked in the question. Once you# represent a BST tree li…

c语言输入一个数存数组,//从键盘上输入若干整数,并将其存入数组中,并统计输入数据的个...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼//从键盘上输入若干整数&#xff0c;并将其存入数组中&#xff0c;并统计输入数据的个数。#include#include#include#includeint sum_num(char [],int []);int cou_num(char [][81],int,int[]);int txt(char [][81],int);//主函数m…

你吃的瓜子仁,真是老奶奶磕出来的?!

全世界只有3.14 % 的人关注了爆炸吧知识本文转载自微信公众号一只学霸&#xff08;ID&#xff1a;bajie203&#xff09;萌萌不是挺爱吃瓜子仁吗有次他吃的时候大毛在旁边看着看着突然想到一个问题吓得我反思了一下自己是怎么和他们考上同个学校的没思考出来吓得我给大家写了这篇…

ASP.NET GridView控件匯出EXCEL-移除控件,只是顯示文本

ASP.NET GridView控件匯出EXCEL-移除控件&#xff0c;只是顯示文本下午 05:10 2011/2/22 將GridView中的TextBox&#xff0c;DropDownList&#xff0c;LinkButton去掉&#xff0c;顯示文本。 public void ClearGridControls(ref Control sourceControl) { for (int i…

android脚步---不同activity之间参数传递

现在有两个activity&#xff0c;一个是mainactivity&#xff0c;一个是detectactivity 后者需要调用前者的一个参数&#xff0c;这里用到了intent getextras(); putextras();参数传递, 看代码&#xff0c;首先两个activity之间有关联&#xff0c;第一个activity里面有一个Butt…

持续20年,一场威胁Linux存亡的诉讼终结束

文 | 局长出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;一场持续将近 20 年、曾被认为会威胁 Linux 存亡的诉讼终于迎来了尾声。这场诉讼开始于 2003 年&#xff0c;不过其背后的事件最早可追溯到 1998 年。当时 IBM 和 Santa Cruz Operation&#xff…

shell grep 变量_老司机给出的关于 shell 脚本的8个建议,必收!

这八个建议&#xff0c;来源于键者几年来编写 shell 脚本的一些经验和教训。事实上开始写的时候还不止这几条&#xff0c;后来思索再三&#xff0c;去掉几条无关痛痒的&#xff0c;最后剩下八条。毫不夸张地说&#xff0c;每条都是精挑细选的&#xff0c;虽然有几点算是老生常谈…

c语言两个长整数相加,二个超长正整数的相加

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼看看这个,定义数组的长度为251,可以实现最长250位的两个整数相加.#include#includemain(){int i;char str1[251]{0};char str2[251]{0};char str_rut[252]{0};int len_str1,len_str2,len_rut0;int flag0; /*定义初始变量*/clrscr()…

python input函数无法输入字符串_Python手把手教程之用户输入input函数

函数input() 函数input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其存储在一个变量中,以方便你使用。 例如,下面的程序让用户输入一些文本,再将这些文本呈现给用户: message = input("Tell me something, and I will repeat it back to you: &…

修改SDE中自动生成的web.xml文件

SDE中的web.xml文件是自动生成&#xff0c;所以&#xff0c;不能直接修改&#xff0c;只能修改SDE的模版文件。<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />模版文件的位置如下&#xff1a;C:\SDE4\Java\tools\settings\prfr…

不是说好一起长大的吗?

1 仿佛闻到了嫉妒的味道&#xff01;2 阿拉&#xff1a;不是说好一起长大的吗&#xff1f;3 还有这么小的菠萝蜜&#xff1f;&#xff1f;4 你以为它是个橘子其实它并不是5 当我吃到自己喜欢吃的东西时……6 以后吃完小龙虾&#xff0c;千万别扔&#xff0c;有妙用7 这是啥玩意…