admin管理员组文章数量:1794759
C# 源代码生成器
C# 源代码生成器
- 什么是源生成器
- 源生成器允许执行两个主要操作
- Microsoft 文档模型图示
- 常见方案
- 源生成器的使用
- 1、创建 .NET控制台应用程序
- 2、创建源生成器项目
- 3、在控制台程序中使用生成器项目
- 结语
源生成器是由.NET Compiler Platform(“Roslyn”)SDK 附带。 通过源生成器,C# 开发人员可以在编译用户代码时检查用户代码。 生成器可以动态创建新的 C# 源文件,这些文件将添加到用户的编译中。 这样,代码可以在编译期间运行。 它会检查你的程序以生成与其余代码一起编译的其他源文件。
- 源生成器是 C# 开发人员可以编写的一种新组件
1、检索表示正在编译的所有用户代码的编译对象。 可以检查此对象,并且可以编写适用于正在编译的代码的语法和语义模型的代码,就像现在使用分析器一样。
2、生成可在编译过程中添加到编译对象的 C# 源文件。 也就是说,在编译代码时,可以提供其他源代码作为编译的输入。
结合使用这两项操作能充分发挥源生成器的强大功能。 可以使用编译器在编译时构建的丰富元数据检查用户代码。 然后,生成器将 C# 代码发送回基于已分析数据的同一编译。 如果你熟悉 Roslyn 分析器,可以将源生成器视为可发出 C# 源代码的分析器。
Microsoft 文档模型图示源生成器作为编译阶段运行
源生成器是由编译器与任何分析器一起加载的 .NET Standard 2.0 程序集。 它在可以加载和运行 .NET Standard 组件的环境中使用。
目前只有 .NET Standard 2.0 程序集可以用作源生成器。
常见方案- 运行时反射
- 处理 MSBuild 任务
- 交织中间语言 (IL)
可用于检查用户代码,并基于当今技术所使用的分析生成信或代码。 详细内容参考Microsoft 文档
源生成器的使用 1、创建 .NET控制台应用程序不使用顶级语句, 经典格式是必需的
强行使用顶级语句会报: 错误 CS0759 没有为分部方法“Program.HelloFrom(string)”的实现声明找到定义声明 方法未声明的错误
namespace SourceCodeConsole { public partial class Program { static void Main(string[] args) { HelloFrom("Generated Code"); } static partial void HelloFrom(string name); } } 2、创建源生成器项目引入NuGet包: Microsoft.CodeAnalysis.CSharp Microsoft.CodeAnalysis.Analyzers
继承 ISourceGenerator 并实现接口方法,也要为实现类添加[Generator]特性支持
using Microsoft.CodeAnalysis; using System.Diagnostics; namespace HelloSourceCode { [Generator] public class HelloSourceGenerator : ISourceGenerator { public void Execute(GeneratorExecutionContext context) { // 找到主方法 var mainMethod = context.Compilation.GetEntryPoint(context.CancellationToken); // 构建源代码 string source = $@"// <auto-generated/> using System; namespace {mainMethod.ContainingNamespace.ToDisplayString()} {{ public static partial class {mainMethod.ContainingType.Name} {{ static partial void HelloFrom(string name) => Console.WriteLine($""Generator says: Hi from '{{name}}'""); }} }} "; var typeName = mainMethod.ContainingType.Name; // 将源代码添加到编译中 context.AddSource($"{typeName}.g.cs", source); } public void Initialize(GeneratorInitializationContext context) { // 不需要初始化 // 附加调试器进程 //if (!Debugger.IsAttached) //{ // Debugger.Launch(); //} } } }从 context 对象中,我们可以访问编译的入口点或 Main 方法。 mainMethod 实例是一个 IMethodSymbol,它表示一个方法或类似方法的符号(包括构造函数、析构函数、运算符或属性/事件访问器)。 Microsoft.CodeAnalysis.Compilation.GetEntryPoint 方法返回程序的入口点的 IMethodSymbol。 其他方法使你可以查找项目中的任何方法符号。 在此对象中,我们可以推理包含的命名空间(如果存在)和类型。 此示例中的 source 是一个内插字符串,它对要生成的源代码进行模板化,其中内插的缺口填充了包含的命名空间和类型信。 使用提示名称将 source 添加到 context。 对于此示例,生成器创建一个新的生成的源文件,其中包含控制台应用程序中 partial 方法的实现。 可以编写源生成器来添加任何喜欢的源。
GeneratorExecutionContext.AddSource 方法中的 hintName 参数可以是任何唯一名称。 通常为该名称提供显式 C# 文件扩展名,例如 ".g.cs" 或 ".generated.cs"。 该文件名有助于将文件标识为正在生成源。
关于 Initialize 方法一般是不用初始化的,上面可以看到我是写了一段代码的,作用是进入调试,这样做的主要原因是,不进行附加是无法进行调试的
3、在控制台程序中使用生成器项目 <ItemGroup> <ProjectReference Include="..\\HelloSourceCode\\HelloSourceCode.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup>新引用不是传统的项目引用,必须手动编辑以包含 OutputItemType 和 ReferenceOutputAssembly 属性。
-
运行结果
-
查看生成的代码
本文学术内容皆引用于 Microsoft 文档 部分详细内容,本篇不再说明,Microsoft 文档说得很明确:文档地址 learn.microsoft/zh-cn/dotnet/csharp/roslyn-sdk/
版权声明:本文标题:C# 源代码生成器 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1687009611a128279.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论