C# SourceGenerator 源生成器初探

简介

注意: 坑极多。而且截至2023年,这个东西仅仅是半成品

利用SourceGenerator可以在编译结束前生成一些代码参与编译,比如编译时反射之类的,还有模板代码生成都很好用。

演示仓库传送门-Github-yueh0607

使用

1. 创建项目

我们需要两个项目,创建完如下

  1. 类库项目(用作生成器)(注意只能是.NET Standard 2.0 ,别的无效)
  2. 控制台项目(用来测试)(至少是.NET 5.0或者以上,建议是6,7)
    在这里插入图片描述

2.安装CodeAnalysis.Common包

在这里插入图片描述
注意:这个包是依赖Roslyn编译器的,所以请把VisualStudio更新到最新,这一点相当重要,或者你自行保证 编译器版本符合这个Nuget包的要求,如果不符合,在VS的警告里会发出提示。

严重性 说明 行
警告 分析器程序集“X:\Projects\ImportantProjects\SourceGenTest\SourceGen\bin\Debug\netstandard2.0\SourceGen.dll”引用了编译器的版本“4.6.0.0”,该版本高于当前正在运行的版本“4.4.0.0”。 1

3.写生成器

  1. 注意要实现ISourceGenerator接口
  2. 加上特性Generator (可以不写参数,也可以写"C#",或者我这么写也行)
  3. 尽量使用完全限定来防止名称冲突,global能进一步防止撞名字
  4. 使用"""三个引号能写格式化代码,很方便
  5. 记得打上特性标记代码由编译器生成,而非用户生成或者书写的,防止被滥用
using Microsoft.CodeAnalysis;namespace SourceGen
{[Generator(LanguageNames.CSharp)]public sealed class HelloWorldGenerator : ISourceGenerator{void ISourceGenerator.Execute(GeneratorExecutionContext context){const string version = "1.0";context.AddSource("TestFile.cs",$$"""//<auto-generated/>#nullable enablenamespace GenCode{[global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{nameof(HelloWorldGenerator)}}","{{version}}")][global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]public static class GeneraredClass{[global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{nameof(HelloWorldGenerator)}}","{{version}}")][global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]public static void Hello(){global::System.Console.WriteLine("代码生成成功");}}}""");}//初始化,可以写一些筛选条件之类的void ISourceGenerator.Initialize(GeneratorInitializationContext context){}}
}

在这里插入图片描述
写完就出警告了,在生成器项目需要添加Enforce…加上就OK了
在这里插入图片描述

4.引用生成器

在这里插入图片描述
在这里插入图片描述
引用完之后,在ItemGroup里只有Include,手动加上后两项。注意不要写错字母

注意本文内使用的C#版本较高,可能需要手动打开preview模式
在这里插入图片描述
在这里插入图片描述

生成器每次改动都需要重新生成这个项目!!!,建议第一次也重新生成

5.玄学施法时刻

重启VS
在这里插入图片描述
在这里插入图片描述
这样测试项目里就生成完毕了

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

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

相关文章

flutter 导出iOS问题2

问题1:The Swift pod FirebaseCoreInternal depends upon GoogleUtilities, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries) 参考 正如上图报错第三方…

AI生成式视频技术来临:Runway Gen-2文本生成视频

Runway Gen-2的官方网站提供了一种文本生成视频的工具。以下是对该工具的介绍&#xff1a; 文本生成视频&#xff1a;Runway Gen-2是一个创新的在线工具&#xff0c;可以将文本转化为视频。用户只需输入文本描述或句子&#xff0c;Runway Gen-2就能自动生成相应的视频内容。这…

机器学习-New Optimization

机器学习(New Optimization) 前言&#xff1a; 学习资料 videopptblog 下面的PPT里面有一些符号错误&#xff0c;但是我还是按照PPT的内容编写公式&#xff0c;自己直到符号表示什么含义就好了 Notation 符号解释 θ t \theta_t θt​第 t 步时&#xff0c;模型的参数 Δ L …

数据结构---并查集

目录标题 为什么会有并查集并查集的原理模拟实现并查集准备工作构造函数FindRootUnionSetCount 并查集实战题目一&#xff1a;省份数量题目解析题目二&#xff1a;等式方程的可满足性题目解析 为什么会有并查集 这里可以使用生活中的一个例子来带着大家理解并查集&#xff0c;…

深入理解 SQL:从基本查询到高级聚合

目录 背景理论知识示例1211. 查询结果的质量和占比&#xff08;Round group by&#xff09;1204. 最后一个能进入巴士的人 &#xff08;Having limit order by&#xff09;1193. 每月交易 I&#xff08;if group by&#xff09;1179. 重新格式化部门表1174. 即时食物配送 II&am…

JVM总结笔记

JVM JVM是什么?JVM 的主要组成部分JVM工作流程JVM内存模型直接内存与堆内存的区别&#xff1a;堆栈的区别Java会存在内存泄漏吗&#xff1f;简述Java垃圾回收机制垃圾收集算法轻GC(Minor GC)和重GC(Full GC)新生代gc流程JVM优化与JVM调优 JVM是什么? JVM是Java Virtual Mach…

Linux操作系统2-软件的安装

软件安装方式 二进制发布包安装 软件已针对具体平台编译打包&#xff0c;只需要解压、修改配置rpm安装 安装按照redhat的包管理规范进行打包&#xff0c;使用rpm命令进行安装&#xff0c;不能自行解决库依赖问题yum安装 一种在线软件安装方式&#xff0c;本质上还是rpm安装&am…

【LeetCode每日一题】——766.托普利茨矩阵

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【题目进阶】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 766.托普利茨矩阵 四【题目描述…

使用Roles模块搭建LNMP架构

使用Roles模块搭建LNMP架构 1.Ansible-playbook中部署Nginx角色2.Ansible-playbook中部署PHP角色3.Ansible-playbook中部署MySQL角色4.启动安装分布式LNMP 1.Ansible-playbook中部署Nginx角色 创建nginx角色所需要的工作目录&#xff1b; mkdir -p /etc/ansible/playbook/rol…

react中的高阶组件理解与使用

一、什么是高阶组件&#xff1f; 其实就是一个函数&#xff0c;参数是一个组件&#xff0c;经过这个函数的处理返回一个功能增加的组件。 二、代码中如何使用 1&#xff0c;高级组件headerHoc 2&#xff0c;在普通组件header中引入高阶组件并导出高阶组件&#xff0c;参数是普…

Leetcode | DP | 338. 198. 139.

338. Counting Bits 重点在于这张图。 从i1开始&#xff0c;dp的array如果i是2的1次方之前的数&#xff0c;是1 dp[i - 2 ^ 0]; 如果i是2的2次方之前的数&#xff0c;是1 dp[i - 2 ^ 1]; 如果i是2的3次方之前的数&#xff0c;是1 dp[i - 2 ^ 2]; 198. House Robber 如果…

zookeeper学习(三)基础数据结构

数据模型 在 zookeeper 中&#xff0c;可以说 zookeeper 中的所有存储的数据是由 znode 组成的&#xff0c;节点也称为 znode&#xff0c;并以 key/value 形式存储数据。 整体结构类似于 linux 文件系统的模式以树形结构存储。其中根路径以 / 开头。 进入 zookeeper 安装的 …

【机器学习】Gradient Descent for Logistic Regression

Gradient Descent for Logistic Regression 1. 数据集&#xff08;多变量&#xff09;2. 逻辑梯度下降3. 梯度下降的实现及代码描述3.1 计算梯度3.2 梯度下降 4. 数据集&#xff08;单变量&#xff09;附录 导入所需的库 import copy, math import numpy as np %matplotlib wi…

CompletableFuture 详解

目录 简单介绍 常见操作 创建 CompletableFuture new 关键字 静态工厂方法 处理异步结算的结果 简单介绍 CompletableFuture 同时实现了 Future 和 CompletionStage 接口。 public class CompletableFuture<T> implements Future<T>, CompletionStage<T…

selenium-web自动化测试

一、selenium环境部署 1.准备chrome浏览器&#xff08;其他浏览器也行&#xff09; 2.准备chrome驱动包 步骤一&#xff1a;查看自己的谷歌浏览器版本(浏览器版本和驱动版本一定要对应) 步骤二&#xff1a;下载对应的驱动包, 下载路径 : ChromeDriver - WebDriver for Chrom…

初识IDA工具

工具 IDA工具 链接&#xff1a;https://pan.baidu.com/s/1Zgzpws6l2M5j1wkCZHrffw 提取码&#xff1a;ruyu 里面有安装密码&#xff1a; PassWord:qY2jts9hEJGy 里面分析32位和64位启动快捷方式 打开IDA工具&#xff0c;拖入so文件 ARM AND THUMB MODE SWITCH INSTRUCTION…

PyTorch BatchNorm2d详解

通常和卷积层&#xff0c;激活函数一起使用

视频传输网安全防护体系

在电脑、手机信息安全保护得到广泛关注和普及的今天&#xff0c;监控摄像头等设备的安全防护仍为大众所忽略&#xff0c;大量视频监控网络的前端设备和数据没有任何保护&#xff0c;完全暴露在互联网中。 前端IP接入设备与后端业务系统处于直连状态&#xff0c;一旦有攻击者或…

spring boot项目整合spring security权限认证

一、准备一个spring boot项目 1、引入基础依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.sp…

自定义类型讲解

&#x1f495;痛苦难道是白忍受的吗&#xff1f;&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;自定义类型讲解 一.结构体 定义&#xff1a; 数组&#xff1a;多组相同类型元素的集合 结构体&#xff1a;多组不同类型元素的集合-->管理多组不同类型数据…