LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

初识 C# 源代码生成器,编写代码的代码

admin
2025年1月3日 21:8 本文热度 139

前言

嗨,大家好!

今天我们来聊一聊 C# 里的源代码生成器,一个有趣的代码生成工具。

源代码生成器(Source Generators)是 C# 9.0 引入的一项强大功能,允许你在编译时动态生成源代码。

这意味着,你可以编写代码来自动生成其他代码,从而减少手动重复的工作。

这个过程在编译阶段发生,生成的代码会在编译输出中包含,从而使你的类库或应用程序更轻便、更可维护。

首先我们通过一个 Step By Step 例子来感受一下它的魅力吧!

Step By Step 例子

我们来创建一个源生成器,它可以自动为一个类生成一个 ToString 方法,方便快速打印统一的对象信息

1. 创建项目

  • 在 Visual Studio 2022 IDE 中,创建一个新的类库项目,命名为 SourceGen

  • 选择 .NET Standard 2.0 版本,如图:

2. 添加 NuGet 包

<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />

注意:

  1. 不要选择太高的版本,否则可能会出现编译器版本太高的问题,比如:

    分析器程序集“...”引用了编译器的版本 “4.12.0.0”,该版本高于当前正在运行的版本 “4.8.0.0”
  2. 包 Microsoft.CodeAnalysis.CSharp 已经包含了 Microsoft.CodeAnalysis.Analyzers,所以无需继续添加此包

3. 配置 EnforceExtendedAnalyzerRules 规则

打开项目文件 SourceGen.csproj,在 PropertyGroup 节点下手动增加 EnforceExtendedAnalyzerRules 配置,如图:

4. 创建源生成器

在项目中,创建一个新的类文件,命名为 ToStringGenerator.cs,并编写以下代码:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespaceSourceGen
{
    [Generator]
    publicclassToStringGenerator : ISourceGenerator
    {
        public void Execute(GeneratorExecutionContext context)
        {
            var syntaxTrees = context.Compilation.SyntaxTrees;

            foreach (var tree in syntaxTrees)
            {
                var root = tree.GetRoot();
                var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();

                foreach (var classDeclaration in classes)
                {
                    // 获取类名
                    var className = classDeclaration.Identifier.Text;
                    // 获取类成员
                    var properties = classDeclaration.Members.OfType<PropertyDeclarationSyntax>();
                    var propertiesList = string.Join(", ", properties.Select(p => $"{p.Identifier.Text} = {{{p.Identifier.Text}}}"));

                    // 写 ToString 方法
                    // 注意这里用了 partial 修饰符
                    var toStringMethod = $@"
public partial class {className} {{
    public override string ToString() => ""{className} {{{propertiesList}}}"";
}}
                "
;
                    context.AddSource($"{className}_ToString.g.cs", SourceText.From(toStringMethod, Encoding.UTF8));
                }
            }
        }

        public void Initialize(GeneratorInitializationContext context)
        {
            // 可以在这里初始化任何需要的对象或资源
        }
    }
}

编译一下确定代码没问题。

5. 创建新控制台项目

在解决方案中,添加一个新的控制台项目,命名为 SourceGeneratorSample

6. 引用源代码生成器项目 SourceGen

注意,引用后,需要打开 SourceGeneratorSample.csproj,修改项目引用节点内容,添加 OutputItemType 和 ReferenceOutputAssembly 配置:

<ProjectReference Include="..\SourceGen\SourceGen.csproj" 
                OutputItemType="Analyzer" 
                ReferenceOutputAssembly="false" />

7. 定义一个类

在 SourceGeneratorSample 项目中,创建一个简单的类,例如 Person

public partial class Person
{
    public string? Name { getset; }
    public int Age { getset; }
}

注意:

  1. 不要放在任何命名空间下

  2. 使用 partial 修饰符

8. 使用源代码器生成的方法

在 Program.cs 文件中,创建一个 Person 实例对象并打印它的 ToString

var person = new Person { Name = "Alice", Age = 30 };
Console.WriteLine(person.ToString()); 

9. 运行

按 Ctrl+F5 编译并运行程序,你会在控制台看到如下图输出:

优势与劣势

在上面的例子里,我们为项目中所有的类统一了 ToString 方法的输出,从中我们可以看出一些源代码生成器的优势和劣势:

优势

  1. 减少重复劳动:源代码生成器可以自动生成一些繁琐的重复性代码,特别是那些不变的基本数据结构或方法,比如数据传输对象(DTO)或实体类。

  2. 提高代码一致性:生成的代码遵循预设的逻辑,可以更好地保持一致性,减少了人为错误

  3. 保持代码整洁:将生成的代码与手写的代码分开,主代码会显得更加清晰易读

劣势

  1. 编译时错误难以调试:因为代码是在编译阶段生成的,如果生成的代码有问题,定位和修复会相对比较困难

  2. 学习成本:源代码生成器的概念和使用方式跟传统开发方式差别比较大,需要一定的学习时间来掌握其使用方法

  3. 可能增加复杂性:源代码生成器的实现需要对语法树有深入的理解,这可能增加开发的复杂性。

  4. 版本兼容性:如果使用的源生成器依赖于特定版本的编译器或框架,升级时可能会有兼容性的问题

总结

随着 .NET 8 的发布,源代码生成器这一强大特性也逐渐走进了更多程序员的视野。

相比传统的 T4 模板等代码生成工具,源代码生成器的最大魅力在于它能在编译时动态生成代码。

这意味着你生成的代码能立刻融入项目中,无需反复编译,就像魔法一样——写完代码马上就能看到结果,大大提升了开发效率。

不过,任何好东西都有它的 “小脾气”,源代码生成器也不例外,有时候调试它很让人抓狂,特别是如果你对语法树不太熟悉的话,刚开始接触时,可能会觉得有点棘手,需要花点时间去适应和学习。

所以呢,要不要在你的项目里引入这个强大的特性,其实取决于具体情况。如果你的项目适合并且你能接受一点初期的学习成本,那么源代码生成器绝对会让你的开发体验焕然一新。但如果项目时间紧迫或团队成员对它还不够熟悉,可能就需要再三考虑一下啦。


该文章在 2025/1/6 10:15:30 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved